Compilación de un kernel a medida

¿Qué es un kernel?

Un kernel es el núcleo de un sistema operativo. Es el encargado de gestionar los recursos del sistema, como la memoria, los procesos, los dispositivos de entrada y salida, etc. Es el primer programa que se ejecuta cuando se enciende el ordenador.

¿Por qué compilar un kernel?

La mayoría de los sistemas operativos modernos utilizan un kernel compilado por el fabricante del sistema. Esto es así porque el kernel es un programa muy complejo y que requiere de una gran cantidad de recursos para su compilación. Por ello, es más fácil que el fabricante del sistema lo compile y lo distribuya junto con el resto del sistema operativo.

Sin embargo, hay algunas ventajas de compilar un kernel a medida:

  • Personalización: se puede personalizar el kernel para que se adapte a las necesidades del usuario. Por ejemplo, se puede añadir soporte para un dispositivo que no está soportado por el kernel del sistema operativo.
  • Optimización: se puede optimizar el kernel para que se adapte a las características del hardware del sistema. Por ejemplo, se puede añadir soporte para un procesador que no está soportado por el kernel del sistema operativo.
  • Seguridad: se puede añadir soporte para cifrado de disco, cifrado de memoria, etc.
  • Estabilidad: se puede añadir soporte para el uso de un sistema de ficheros de alto rendimiento, como Btrfs.
  • Rendimiento: se puede añadir soporte para el uso de un sistema de ficheros de alto rendimiento, como Btrfs.
  • Compatibilidad: se puede añadir soporte para el uso de un sistema de ficheros de alto rendimiento, como Btrfs.
  • Rendimiento: se puede añadir soporte para el uso de un sistema de ficheros de alto rendimiento, como Btrfs.

Por ello, en este artículo vamos a ver cómo compilar un kernel a medida.

¿Qué necesitamos?

Para compilar un kernel a medida necesitamos:

  • Un sistema operativo. En este artículo vamos a utilizar Ubuntu Debian 11 Bullseye.
  • Un compilador de C. En este artículo vamos a utilizar qtbase5-dev.
  • Un sistema de ficheros de alto rendimiento (Btrfs).

Preparando el escenario

Lo primero de realizaremos será preparar la máquina en la que vamos a compilar el kernel. Para ello, crearemosun directorio donde gestionaremos todo el proceso de compilación del kernel. En este directorio descargaremos el código fuente del kernel.

mkdir kernel
cd kernel

Tras esto, descargaremos el código fuente del kernel. Para averiguar la versión del kernel que tenemos instalado en nuestro sistema, ejecutaremos el siguiente comando:

maria@maria-debian:~kernel$ uname -r
5.10.0-19-amd64

Sabiendo nuestra versión, haremos uso del comando wget para descargarnoslo:

maria@maria-debian:~kernel$ wget https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.10.tar.xz

1

Una vez descargado, comprobamos que efectivamente tenemos nuestro fichero descargado en el directorio:

maria@maria-debian:~kernel$ ls -l
total 113876
-rw-r--r-- 1 maria maria 116606704 dic 14  2020 linux-5.10.tar.xz

Y procedemos a descomprimirlo:

maria@maria-debian:~kernel$ tar -xvf linux-5.10.tar.xz

Ya descomprimido todo elcontenido, si realizamos un du -sh veremos que el tamaño del directorio es de 1,1 GB:

maria@maria-debian:~linux-5.10$ du -sh
1,1G	.

¡Comenzamos!

Antes de comenzar, diremos que una vez finalizada la compilación, tenemos que teneren cuenta que el hardware básico incluirá como mínimo:

  • Teclado, ratón y monitor.
  • Interfaz de red, ya sea por cable o por wifi.
  • Consola gráfica de texto, para poder ver los mensajes de error.

Una vez que tenemos todo preparado, vamos a comenzar con la compilación del kernel. Pero antes debemos tener en cuenta que la compilación del kernel es un proceso muy largo y que puede tardar varias horas. Por ello, es recomendable que no lo hagamos en una máquina que estemos utilizando para trabajar.

Otro punto importante a tener en cuenta será que necesitaremos un fichero donde especificaremos tanto los modulos que enlazaremos de forma dinámica o estática, como los que no enlazaremos. Para ello, haremos uso del comando make para generar dicho fichero, que contendrá la configuración actual de nuestro kernel.

make oldconfig

Después de ello, miramos cuantos módulos enlazados tenemos:

maria@maria-debian:~kernel$ egrep '=y' .config | wc -l
2187
maria@maria-debian:~kernel$ egrep '=m' .config | wc -l
4243

Ejecutamos el comando make menuconfig para configurar el kernel, y esta vez vamos a descartar algunos módulos que no necesitamos. Una vez terminado, volvemos a mirar cuantos módulos enlazados tenemos:

maria@maria-debian:~kernel$ egrep '=y' .config | wc -l
1487
maria@maria-debian:~kernel$ egrep '=m' .config | wc -l
100

3

Antes de ejecutar la compilación, vamos a comprobar que tenemos instaladas las dependencias necesarias para compilar el kernel. Para ello, ejecutaremos el siguiente comando:

maria@maria-debian:~kernel$ sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev libudev-dev libpci-dev libiberty-dev autoconf

Efectivamente, faltaban dependecias, por lo que ya podemos ejecutar la compilación del kernel:

maria@maria-debian:~kernel$ make -j4 bindeb-pkg

Tras varios minutos, (en mi caso, dado que tengo un procesador de 8 núcleos, he puesto -j4,), veremos que la compilación ha finalizado, pero nos salta el siguiente error:

  MODPOST vmlinux.symvers
  MODINFO modules.builtin.modinfo
  GEN     modules.builtin
BTF: .tmp_vmlinux.btf: pahole (pahole) is not available
Failed to generate BTF for vmlinux
Try to disable CONFIG_DEBUG_INFO_BTF
make[3]: *** [Makefile:1170: vmlinux] Error 1
make[2]: *** [debian/rules:7: build-arch] Error 2
dpkg-buildpackage: fallo: debian/rules binary subprocess returned exit status 2
make[1]: *** [scripts/Makefile.package:83: bindeb-pkg] Error 2
make: *** [Makefile:1533: bindeb-pkg] Error 2

Para solucionarlo, deberemos modificar el fichero .config y desactivar la opción CONFIG_DEBUG_INFO_BTF:

2

Tras finalizar la compilación, y quitar módulos innecesarios el tamaño del directorio ha bajado a GB:

maria@maria-debian:~kernel$ ls -lh ..
total 237M 

4

Como podemos ver en la siguiente imágen, el tamaño del fichero .deb es ahora de 5,6 MB, en lugar de los 1,1 GB que teníamos antes:

Instalación del kernel

  • Instalamos el kernel:
maria@maria-debian:~kernel$ sudo dpkg -i linux-headers-5.10.0_5.10.0-1_amd64.deb

5

  • Reiniciamos el sistema:
maria@maria-debian:~kernel$ sudo reboot
  • Comprobamos que el kernel se ha instalado correctamente:
maria@maria-debian:~kernel$ uname -r
5.10.0-1-amd64

6

  • Realizamos un ping al exterior para ver que la red funciona correctamente:
maria@maria-debian:~kernel$ ping -c 5 8.8.8.8

7

Errores encontrados y solución

Una vez compilado el kernel, al intentar instalarlo, nos salta el siguiente error:

 
Warning: os-prober will be executed to detect other bootable partitions.
Its output will be used to detect bootable binaries on them and create menu boot entries.

Para solucionarlo, tendremos que:

  • Ignore la advertencia, es solo una advertencia, no un error.

  • Configuramos la variable GRUB_DISABLE_OS_PROBER=false en /etc/default/grub. La advertencia cambiará a os-prober se ejecutará para detectar....

  • Eliminamos el bit ejecutable de /etc/grub.d/30_os-prober. Esto evitará la ejecución del script, por lo que no podrá recibir ninguna de estas advertencias. Podemos realizar:

sudo chmod -x /etc/grub.d/30_os-prober
  • Por último, editamos el script /etc/grub.d/30_os-prober. Si comentamos las líneas con grub_warn, el script se ejecutará sin emitir estas advertencias.
...
if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then
  grub_warn "$(gettext_printf "os-prober will not be executed to detect other > bootable partitions. \nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.")"
  exit 0
fi

grub_warn "$(gettext_printf "os-prober will be executed to detect other bootable partitions.\nIts output will be used to detect bootable binaries on them and create new boot entries.")"
...

Conclusiones

En este artículo hemos visto como compilar un kernel desde cero, y como instalarlo en nuestro sistema. También hemos visto como reducir el tamaño del kernel, y como comprobar que el kernel se ha instalado correctamente.

También debo aclarar que realice una reducción mínima del kernel, pero por incompatibilidad con mi tarjeta gráfica, no pude hacerlo funcionar. Sin embargo en otra máquina virtual, con una tarjeta gráfica compatible, si que pude hacerlo funcionar.

8