Cómo compilar un Kernel

Linux Nivel Alto 7 de nov. de 2023

¿Porqué compilar un Kernel?

Una de las mejores razones para compilar un kernel es para aprender cómo funciona el Kernel de Linux, ampliar conocimientos sobre el hardware de nuestra máquina y saber como funciona el sistema operativo.

También sirve para optimizar el funcionamiento del Kernel y desactivar o activar funciones que necesitemos o no en él.

Otra razón para compilar es  disponer de la última versión y poder usar las nuevas funcionalidades en cuanto están disponibles.

Dónde obtener el Kernel de Linux

Podemos descargar el código fuente del Kernel de Linux desde:

The Linux Kernel Archives
www.kernel.org

En este tutorial vamos a compilar la última versión disponible del Kernel, la versión 6.6, para ello descarga el 'tarball' de esta versión:
https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.tar.xz

Descomprime en fichero en una ruta de tu equipo, ten en cuenta el espacio que ocupará.
Una vez extraido unicamente serán unos 1.5Gb,  pero cuando realices la compilación ocupará bastante más, necesitarás como mínimo 7Gb de espacio.

Para nuestro ejemplo, crearemos una carpeta que se llame 'mis-kernels' que podemos crear, por ejemplo, dentro del directorio 'Descargas'.

Nota: No es necesario dejarlo en /usr/src la compilación e instalación funcionará correctamente incluso si lo realizamos en otra ruta diferente a las denominadas como 'estandard'.

Para extraer el Kernel descargado simplemente ejecuta el comando:

tar -xvf linux-6.6.tar.xz
Descomprimir el Kernel

Aplicaciones y librerías necesarias para compilar

Para compilar el Kernel en Debian, deberemos instalar varias herramientas, para ello abre tu terminal y ejecuta lo siguiente:

sudo apt -y install autoconf automake autotools-dev bison build-essential dh-make debhelper debmake devscripts dpkg fakeroot file flex gfortran git gnupg fp-compiler lintian patch pbuilder perl quilt xutils-dev

Pasos para la compilación del Kernel

Para simplificar el proceso y evitar confusiones entre ejecuciones de comandos entre nuestro usuario y root, en este caso vamos a realizar todas las tareas como root.

Podemos compilar el Kernel desde cero, pero es un trabajo duro y requiere de conocimientos detallados de muchos apartados y opciones. A pesar de todo se puede "escapar" algo y olvidarnos de incluir alguna opción necesaria en algún apartado.  
Para evitar este trabajo, aprovecharemos la configuración de nuestro kernel actual para partir de una base.

Podemos averiguar nuestra versión de Kernel actual usaremos el comando uname:

uname -r
6.1.0-13-amd64    <-- Nuestro kernel en uso (6.1.0-13)

Vamos a situarnos en el directorio del kernel que descargamos y hemos extraído antes:

cd linux-6.6

El índice de los pasos a realizar es el siguiente:

  1. Usar config base del kernel actual.
  2. Generar una configuración local con el hardware de nuestra máquina.
  3. Configuración asistida: menuconfig y xconfig. Optimizaremos el kernel incluyendo o quitando hardware, soporte a sistemas de ficheros, escogiendo si hay partes del kernel que queremos usarlas incluidas en él o usarlas como módulos.
  4. Compilación del kernel y módulos.
  5. Instalación del kernel y preparar su inicio.
  6. Pruebas y aceptación del nuevo Kernel (y vuelta atrás).

Reutilización de la configuración del kernel actual

Para la compilación del Kernel se utiliza un fichero .config que usará el comando make para construirlo.

Vamos a usar el fichero de configuración del kernel actual en uso para simplificar el proceso, para ello lo copiaremos en nuestro directorio actual del código fuente y lo cambiaremos de nombre, lo hacemos directamente con el siguiente comando:

cp /boot/config-$(uname -r) .config
Copiar configuración del kernel en uso actual

Ajuste de la configuración al hardware de nuestro equipo

Para simplificar aún más la configuración con respecto al hardware de nuestro equipo en el que estamos compilando, usaremos el siguiente comando:

make localmodconfig
Nota: Si vamos a realizar la compilación para generar un kernel para otro tipo de equipo/servidor con hardware distinto, deberemos revisar en el siguiente paso el hardware y otros parámetros a incluir o excluir en la configuración para optimizarlo para ese hardware específico.

Configuración asistida: menuconfig / xconfig

Para poder ajustar la configuración del kernel hay 3 formas posibles de realizarlo:

  1. Configuración paso a paso

Se ejecuta mediante el comando:

make config
Configuración del kernel paso a paso

Este configuración se considera ya obsoleta. Es muy lenta y tediosa y lleva mucho tiempo, si te equivocas tienes que volver a pasar por los mismos pasos anteriores.
Os dejo una captura, como curiosidad, de los primeros pasos de como sería el proceso:

make config (Configuración obsoleta paso a paso)

2. Configuración con menús de texto

Ésta es la opción más usada para la compilación del Kernel, se utiliza si no dispones de un entorno gráfico instalado en tu equipo (por ejemplo si compilas el kernel desde un servidor). Para iniciarlo ejecuta:

make menuconfig

Verás un menú en modo texto similar al siguiente:

make menuconfig (Configuración del kernel mediante menús de texto)

La manera de usarlo es mediante las flechas del teclado, el tabulador para cambiar entre opciones y la barra espaciadora para marcar/desmarcar opciones o cambiar algo a tipo 'modulo'.

En la captura anterior, hemos marcado 'Virtualización', deberemos entrar en las subopciones de esta opción. Para ello una vez marcado hay que escoger 'Select' para acceder y dentro de esta opción escoger lo que deseemos:

Opciones extras a la opción 'Virtualización'

Si queremos disponer de algo de ayuda sobre lo que estamos seleccionando, deberemos ir hasta 'Help' para que nos muestre un menú con la información de la opción actual:

'Help' - Ayuda en modo texto sobre la opción que estamos configurando

3. Configuración con menú gráfico

Podemos usar un asistente gráfico para la configuración usando el comando:

make xconfig
make xconfig (Configurar el Kernel con asistente gráfico)

Ésta quizás sea una de las formas más amigables, para los que se inician en la compilación de un Kernel. Podemos usar el ratón para seleccionar y marcar/desmarcar las opciones disponibles ➊, ver cada uno de las subopciones que aparecen al marcar cada una de ellas ➋ y además disponemos en la parte inferior de una ayuda ➌ que nos indica que estamos tocando y nos indica que opción escoger en caso de que desconozcamos lo que estamos seleccionando.

Ajuste de la configuración del Kernel
Independientemente del modo que usemos para configurar el kernel, debemos ir recorriendo todas y cada de las opciones para poner o quitar soporte al hardware que queramos, a los sistemas de ficheros extras a usar, uso de soporte raid de distintos fabricantes, formas de gestionar la memoria, uso de hardware 'legacy', etc...
Si tienes dudas sobre algo, lo mejor es dejar la opción tal y como aparezca ya sea marcada o desmarcada.

Hay opciones que permiten ser seleccionadas como módulos (module), esto significa que el kernel generado será menos pesado en tamaño y podrás cargar o quitar esas partes de gestión de hardware o File System si no las necesitas, ahorrando memoria en tiempo de ejecución.
El uso de un módulo tiene la desventaja que es más lento a la hora del acceso, se obtien más rendimiento si dejamos la opción seleccionada para ser incluida en el propio kernel.
Tienes que 'jugar' con lo que consideras básico para funcionar y que extras quieres para dejarlo como módulo y obtener una mejor optimización entre consumo de memoria y velocidad.  

Algunas de las mejoras del Kernel 6.6 son respecto a EXT4, que ahora tiene una mejora del rendimiento del 34 % en escrituras simultáneas, mejoras en NVidea (Nouveau) para preparar el soporte a su driver NVK (Vulkan), configuración de la BIOS de equipos HP directamente desde Linux,  planificación de clústeres para los procesadores híbridos de Intel (Alder Lake, Raptor Lake y posteriores), entrada-salida directa asíncrona usando io_uring que aumenta el rendimiento en un 37% y sobresale sobre todo el nuevo planificador de tareas, EEVDF (Earliest Eligible Virtual Deadline First).

Ejemplo de opciones necesarias para usar Docker y Docker Swarm
Una de las partes que puede que te fallen, pueden ser los servicios para gestión de contenedores (Docker y Docker Swarm), si los usas deberás tener activado en la configuración del kernel varias opciones, entre ellas la opción de CONFIG_IPVLAN

Otras opciones necesarias que debes de habilitar para usar Docker son:

  • cgroup hierarchy
  • CONFIG_NAMESPACES
  • CONFIG_NET_NS
  • CONFIG_PID_NS
  • CONFIG_IPC_NS
  • CONFIG_UTS_NS
  • CONFIG_CGROUPS
  • CONFIG_CGROUP_CPUACCT
  • CONFIG_CGROUP_DEVICE
  • CONFIG_CGROUP_FREEZER
  • CONFIG_CGROUP_SCHED
  • CONFIG_CPUSETS
  • CONFIG_MEMCG
  • CONFIG_KEYS
  • CONFIG_VETH (puedes usarla como módulo)
  • CONFIG_BRIDGE
  • CONFIG_BRIDGE_NETFILTER (puedes usarla como módulo)
  • CONFIG_NF_NAT_IPV4 (puedes usarla como módulo)
  • CONFIG_IP_NF_FILTER (puedes usarla como módulo)
  • CONFIG_IP_NF_TARGET_MASQUERADE (puedes usarla como módulo)
  • CONFIG_NETFILTER_XT_MATCH_ADDRTYPE (puedes usarla como módulo)
  • CONFIG_NETFILTER_XT_MATCH_CONNTRACK (puedes usarla como módulo)
  • CONFIG_NETFILTER_XT_MATCH_IPVS (puedes usarla como módulo)
  • CONFIG_IP_NF_NAT (puedes usarla como módulo)
  • CONFIG_NF_NAT (puedes usarla como módulo)
  • CONFIG_NF_NAT_NEEDED
  • CONFIG_POSIX_MQUEUE

Una vez finalizada la configuración con lo que deseemos, grabaremos el fichero y estará disponible para su compilación.

Extra para tu configuración del Kernel con Docker
Seguramente antes de compilar, quieras saber si las opciones que has seleccionado para crea tu Kernel van a funcionar correctamente con Docker. Para comprobarlo, tan sólo tienes que descargarte el script bajo estas líneas para chequear la configuración generada:

Luego darle permisos de ejecución y comprobar el fichero .config que hemos generado:

# Permisos de ejecucion al chequeador kernel para docker
chmod +x check-config.sh

# Comprobar si la configuración es correcta
check-config.sh .config

Revisa la salida:

Revisando configuración del kernel para Docker

Si hay algo que te falte, simplemente vuelve a ejecutar 'make menuconfig' ó 'make xconfig' para incluirlo, guarda los cambios de la configuración y comprueba de nuevo.

Compilación del Kernel

La parte más difícil para nosotros, que es la revisión detallada de lo que queremos que tenga y haga nuestro kernel ya está realizada, ahora vamos a darle trabajo a nuestro equipo para que compile el kernel.
Para compilar el Kernel, simplemente tienes que ejecutar:

# Compilar usando 1 solo procesador
make 

# Compilar usando todos los procesadores
make -j $(nproc) 
make (Compilando tu propio Kernel !!! )

Una vez compilado el kernel sin errores, tienes que compilar los módulos que seleccionaste en la configuración para usar como módulos extra por el kernel.
Se compilarán e instalarán automáticamente en la ruta necesaria de tu equipo para que sean accesibles por tu nuevo kernel, para ello ejecuta el comando:

make modules_install
Compilación de los módulos
Nota: El proceso de compilación dura bastante tiempo. no desesperes.
Hay veces que incluso más de 1 hora dependiendo de la potencia de tu equipo. Simplemente lanza la compilación y aprovecha para ver alguna de tus películas favoritas...
Esperando a la compilación.... ¿Recuerdas esta película?

Instalación y ajuste del inicio del nuevo Kernel

Si todo ha salido correctamente y no hemos obtenido ningún error en la compilación, ya tenemos preparado nuestro Kernel para poder usarlo.

Para instalarlo simplemente ejecuta:

make install
Instalar el Kernel

Ahora debemos preparar nuestro 'boot-loader' para que pueda iniciar con él.
Para ello ejecuta lo siguiente:

update-grub
update-grub2 
update-initramfs -u

Ya tenemos listo nuestro Kernel, tan solo tenemos que reiniciar y comprobar su funcionamiento:

reboot
Reiniciamos y comprobamos

Comprobación del funcionamiento del Kernel

El nuevo kernel queda seleccionado como opción por defecto para el inicio del sistema, revisa la pantalla en este primer inicio para ver si en el proceso de arranque se produce algún error.
Si el inicio es correcto, tan sólo tendrás que revisar que ningún proceso o aplicación tenga problemas de funcionamiento.

Kernel 6.6 funcionando !!

Enhorabuena, ya tienes tu Kernel funcionando y optimizado.

Cómo volver a un kernel anterior y/o desinstalar el actual

Si nos hemos olvidado de algo o la configuración no es correcta, el equipo no iniciará correctamente o directamente no iniciará...
¡ No hay problema !
Para solucionar el problema de que tu Kernel no sea operativo o no funcione como deseas y quieras iniciar un kernel anterior (que si funcionaba) tan solo tienes que realizar los siguientes pasos:

  1. Reiniciar el equipo
  2. Esperar al menú de Grub y pulsar por ejemplo las flechas de dirección del teclado.
  3. Ir hasta la opción "Advanced options for ..." y pulsar Intro
  4. Escogemos el Kernel anterior y pulsamos Intro para iniciar con él

Veamos ahora cómo eliminar el Kernel que no queremos
Una vez que hayamos arrancado con un kernel anterior que sí funcione, podemos eliminar el kernel de una forma muy sencilla y dejar todo de nuevo al estado anterior.
Para ello realiza los siguientes pasos para eliminar el Kernel 6.6:

# Borrar Kernel
cd /boot
rm config-6.6.0
rm initrd.img-6.6.0
rm System.map-6.6.0
rm vmlinuz-6.6.0

Luego eliminaremos los módulos del kernel 6.6:

# Borrar Módulos
cd /lib/modules
rm -rf 6.6.0

Ajustamos de nuevo GRUB  y reiniciamos nuestro equipo:

# Actualización de GRUB
update-grub
update-grub2

# Reiniciar
reboot

De esta forma volveríamos al estado anterior de la instalación del kernel y dejamos todo de nuevo funcionando tal y como estaba.


Espero que haya sido interesante el artículo.

Si queréis comentar algo sobre el artículo o hacer alguna pregunta, es necesario que estéis registrados. Recordad que podéis haceros miembros de SoloConLinux de forma gratuita.

Etiquetas

Luis GuLo

🐧 SysAdmin GNU/Linux - 🐳 Docker - 🖥️ Bash Scripting - 🐪 Perl - 🐬 MySQL - 👥 Formador de TI - 👥 Formador de SysAdmin's - 💢 Ansible - ☁️ Cloud Computing - ❤️ Debian GNU/Linux