Compilando el kernel

Rafa Morales 13 Septiembre 2013
9min
0
Linux

Hay muchas razones para recompilar el kernel de nuestro sistema, algunas de las cuales son:

  • Hacer un kernel más eficiente y por ello una máquina más rápida.

  • Aumentar la seguridad.

  • Incluir el software necesario para manejar un hardware específico (drivers, módulos).

  • Porque quiere aprender a hacerlo.

A continuación vamos a explicar los pasos generales para actualizar el kernel en un sistema Ubuntu y que, por tanto, serán los mismos a utilizar en Guadalinex. Muchos o la gran mayoría de acciones serán comunes al resto de distribuciones de Linux.

 

Obtener las herramientas necesarias

Para compilar un kernel a medida vamos a necesitar los paquetes build-essential (para el comando make) y kernel-package (para el comando make-kpkg), además de los paquetes gráficos libncurses5-dev y libqt3-dev para elegir las opciones del kernel.

apt-get install build-essential kernel-package libncurses5-dev libqt4-dev

 

Obtener las fuentes del kernel

Las fuentes del kernel las podemos obtener de muchos sitios. El oficial, como ya hemos comentado anteriormente es www.kernel.org. Pero también están en los repositorios de Ubuntu y Debian.

En los repositorios os vais a encontrar las fuentes del kernel con paquetes llamados kernel-source (que son los kernel de Debian) y con paquetes llamados linux-source (que son los kernel de Ubuntu). Sólo tenemos que ejecutar apt-get para descargárnoslo.

apt-get install linux-source

De esta manera se descargará el archivo linux-source-x.x.x.x.tar.bz2 (o .gz según el modo de compresión) con el código fuente del kernel en el directorio /usr/src.

Si en lugar de descargárnoslo del repositorio nos lo descargamos de cualquier otro lugar de Internet, sólo tendremos que situarlo en el mismo directorio anterior /usr/src.

Una vez tengamos las fuentes, ya sea desde un lugar u otro, descomprimiremos el fichero en el mismo directorio, mediante la orden:

tar jxvf linux-x.x.x.x.tar.bz2 -C /usr/src
tar zxvf linux-x.x.x.x.tar.gz -C /usr/src

Lo que creará un directorio llamado igual que el fichero linux-x.x.x.x

 

Configurar el kernel

Configurar el kernel consiste en elegir qué opciones activamos o desactivamos en el kernel que vamos a crear. Para cada opción de configuración, podremos elegir Built-In, Módulo o desactivada.

  • Built-In: De esta manera la opción estará siempre cargada o presente en el kernel y, por tanto, no se podrá descargar de memoria.

  • Módulo: De esta manera podremos cargar o descargar de memoria el objeto en cualquier momento (Se podría asimilar a los drivers de Windows).

  • Desactivada: De esta manera el objeto no estará presente en el kernel ni se podrá posteriormente cargar en memoria, a no ser que lo instalemos.

Un kernel con muchas opciones Built-In es más pesado y ocupa más espacio que uno más modular (con más módulos). Pero cuidado, hay opciones que no deben ser módulos. Por ejemplo, si usas un disco IDE, el soporte para IDE debe ser Built-In y no módulo, ya que el sistema podría no arrancar (mostrando un mensaje de kernel panic).

Hay varias formas de configurar el kernel. Si no tenemos la interfaz gráfica arrancada, en el directorio donde hemos descargado las fuentes ejecutaremos:

/usr/src/linux-x.x.x.x/make menuconfig

Y si tenemos la interfaz gráfica en funcionamiento (necesitaremos el paquete libqt4-dev), ejecutaremos:

/usr/src/linux-x.x.x.x/make xconfig

 

Una vez que hemos terminado de configurar las opciones y le damos a guardar, se crea automáticamente un fichero de configuración con todas las opciones habilitadas. Este fichero se almacena en el mismo directorio del código fuente del kernel con el nombre .config. Nosotros podremos guardar está configuración para futuros usos con otro nombre y en otra ubicación, desde una opción habilitada para ello dentro del menú de configuración.

En ocasiones será interesante partir de una configuración conocida, y no tener que decidir nosotros mismos todas las opciones del kernel. Para ello sólo necesitamos copiar el fichero de configuración que deseemos sobre el fichero .config.

Por ejemplo, muchas distribuciones ya traen el fichero de configuración de la compilación del kernel, podremos usar ese mismo fichero como punto de partida nuestro, aunque sea de una versión anterior.

cp /boot/config-2.6.8.1-3-386 .config /usr/src/linux-x.x.x.x/.config

En este caso deberemos utilizar uno de los siguientes comandos para configurar nuestro kernel. De esta manera, aunque el fichero de configuración sea de una versión anterior, nos irá preguntando una a una qué deseamos hacer con las nuevas opciones que trae el kernel, y posteriormente lanzará el menú de configuración:

make oldconfig menuconfig
make oldconfig xconfig

 

Compilar el paquete del kernel

Para compilar (construir) el paquete con el que instalaremos el nuevo kernel vamos a usar la orden make-kpkg. Admite numerosas opciones y modificadores, pero sólo explicaremos las que más nos pueden hacer falta. Estos comandos los ejecutaremos desde el directorio donde tengamos el código fuente del kernel.

Lo primero que necesitamos es limpiar todos los archivos generados por alguna compilación anterior. Si es la primera vez que compilamos esa versión de kernel no existirán esos ficheros, pero nunca está de más ejecutarlo:

make-kpkg clean

A continuación ejecutaremos la compilación en sí.

El parámetro --append-to-version nos permitirá añadir un número de versión personal en el paquete que creemos, de esta manera lo podremos distinguir de otras compilaciones que hagamos de la misma versión del kernel. Se recomienda no utilizar guiones bajos ni expresiones como -386 o -K7 que ya son utilizados por kernels precompilados.

El parámetro --initrd permite crear automáticamente el disco RAM inicial (initrd – Init RAM Disk). El initrd es un sistema de archivos temporal usado por el kernel durante el inicio del sistema. Como ahora el kernel se puede hacer modular, muchas de las opciones necesarias para el arranque como los sistemas de ficheros, puede que no sean cargadas desde el principio en memoria. Esta imagen nos permitirá tener estas opciones al comienzo del arranque aunque no estén cargadas como built-in en el kernel. Una vez que el kernel ha arrancado, el initrd se descarga de memoria. Este fichero se almacena en /boot/initrd.img-x.x.x.

El parámetro kernel_image genera el kernel compilado.

El parámetro kernel_headers genera las cabeceras asociadas al kernel que estamos compilando.

make-kpkg --append-to-version=.XXX --initrd kernel_image kernel_headers

El anterior comando creará una imagen del kernel en el directorio /usr/src con un nombre de fichero parecido a:

kernel-image-x.x.x.x.XXX_10.00.Custom_i386.deb

 

Instalar el kernel y comprobar GRUB

A continuación deberemos instalar el kernel a partir del archivo generado tras la compilación. Para ello utilizaremos el comando dpkg en el directorio donde se nos ha creado la imagen del kernel:

dpkg -i kernel-image-x.x.x.x.XXX_Custom_i386.deb

Una vez terminado el proceso comprobaremos como se han creado, entre otros, los siguientes ficheros:

  • /boot/initrd.img-x.x.x.XXX: Con la imagen del initrd.

  • /boot/config-x.x.x.XXX: Una copia del fichero .config que almacena la configuración del kernel.

  • /boot/System.map-x.x.x.XXX: Es un fichero de símbolos para el núcleo. Mapea los puntos de entrada de cada una de las funciones en la API del núcleo, al igual que las direcciones de las estructuras de datos del núcleo para el núcleo en ejecución

  • /boot/vmlinuz-x.x.x.XXX: Es un archivo ejecutable enlazado físicamente y que contiene el kernel en uno de los formatos ejecutables soportados por Linux. El vm viene de memoria virtual y la z indica que el fichero está comprimido.

  • /lib/modules/x.x.x.XXX/: Un directorio con los módulos disponibles en el kernel.

Una vez instalado deberemos repasar el fichero de configuración de GRUB para comprobar que el nuevo kernel está configurado para arrancar en el sistema.

Para ello comprobaremos que se encuentran las líneas correspondientes a kernel e initrd apuntando a los ficheros correspondientes.

kernel /boot/vmlinuz-x.x.x-x root=/dev/hda1 ro single
initrd /boot/initrd.img-x.x.x-x

 

Comprobando el initrd

La utilización de initrd puede que en algunas distribuciones no funcione correctamente. Si este es nuestro caso, cuando iniciemos con el kernel nuevo encontraremos un Kernel Panic indicando que no se ha podido cargar /lib/modules. Eso nos indicará que el disco RAM inicial no ha realizado su labor correctamente.

Para solucionar este problema se aconseja utilizar la herramienta initramfs en lugar de initrd. Esta herramienta permite crear un disco RAM con muchas mejoras, como un tamaño personalizado y un sistema de archivos más actualizado. Si vuestra distribución es Debian o Ubuntu se aconseja utilizar este comando para crear el disco RAM inicial.

Si no la tenemos instalada debemos instalar el paquete inintramfs-tools. El parámetro -c indica que cree el disco, y el parámetro -k indica la versión del kernel.

update-initramfs -c -k x.x.x