A menudo me preguntan como compilo mis kernels y que “trucos” uso para hacerlo, hoy me decido a comentar un poco este proceso, y algunos de estos trucos, esto no es una guía paso a paso para novatos, si no una explicación del proceso, centrada en los detalles que YO considero más importantes.
Para empezar, el proceso de compilación del kernel es simplemente seguir una serie de pasos sin ningún tipo de complicación. La complicación en si consiste en configurarlo a medida para nuestro PC (o nuestros Pcs), y que se adapte lo mejor posible a nuestras necesidades.
Para explicar como es este proceso, vamos a poner como ejemplo como compilar el kernel desde sus fuentes originales, descargadas desde su web (kernel.org), pero se podría aplicar, con diferencias en el proceso claro, a la compilación con las fuentes originales de nuestra distribución.
Como esta no es una guía paso a paso, comentar que antes de nada deberías tener ya instalado en vuestro sistema todas las utilidades necesarias para compilar paquetes, por lo general todas las distribuciones explican muy bien en sus respectivas wikis que hay que instalar para construir el kernel, recomiendo mirarlo para ahorrar problemas.
Ahora que ya esta todo aclarado, explicar que se suele realizar todo el proceso en la capeta /usr/src/linux, pero nos da exactamente igual donde se realice. Una vez que ya hemos tomado la dificilísima decisión de en que carpeta compilar nuestro kernel (como si lo queréis hacer en RAM xD) es momento de descargar los sources que vamos a compilar de la web kernel.org, para el ultimo kernel estable a día de hoy (4.17.12) se descargaría así por la terminal “wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.17.12.tar.xz”. Ahora que ya tenemos las fuentes, descomprimimos “tar -xvJf linux-4.17.12.tar.xz” y nos metemos en la carpeta que hemos descomprimido.
Esta carpeta contiene TODO lo que puedes meter en el kernel, pero… eso son muchas cosas y hay que seleccionar, para hacer esto hay distintos comandos, para hacerlo a mano (nos saldrá un menú en ncurses muy chulo para hacerlo) hay que poner “make nconfig” en la terminal (situados en la carpeta que hemos descomprimido claro), pero esto sería un trabajo algo tedioso, por eso voy a explicar mas formas de configurar esto:
¿Y no hay un comando para que me configure todo lo que yo uso exactamente aunque no lo tenga ahora corriendo? Pues no cazurro, por que tu ordenador no es adivino, pero si hay un programa llamado modprobed-db que es capaz de ir guardando en una lista los módulos que vas usando (si lo tienes como demonio), o decirle que te vaya guardando los módulos en la lista cuando le digas, os dejo su entrada en la wiki de arch que lo explica genial (y a mi me da palo explicarlo): https://wiki.archlinux.org/index.php/Modprobed-db Aunque sea la wiki de arch, vale para todas las demás distribuciones.
Con esto ya habríamos configurado los módulos del kernel que necesitamos, si no te apetece usar modprobed-db, o simplemente tu religión te lo impide, puedes usar el comando oldconfig e ir deseleccionando los módulos que crees no usarás con nconfig, es una experiencia ciertamente constructiva, aunque un poco coñazo (hablamos de literalmente todos los puñeteros drivers que soporta el kernel linux por defecto).
Pero configurar el kernel no sólo es configurar los módulos, hay muchas opciones interesantes de configurar relacionadas con el propio funcionamiento del kernel que pueden hacer que se adapte mejor el kernel a vuestras necesidades, un ejemplo de esto es ajustar la frecuencia y la latencia del kernel. Ambas son opciones dentro de la configuración del kernel, la primera nos determina cuantas veces por segundo el kernel hará que la cpu deje de hacer su trabajo para ver si tiene otras tareas con mas prioridad por hacer, por lo tanto a mayor frecuencia se repartirá mejor la carga entre procesos e hilos, pero los terminará más tarde. Esto es util por ejemplo cuando queremos que un ordenador este siempre atento a lo que le decimos, y queremos un buen I/O, algo que yo agradezco en mis ordenadores personales cuando quiero hacer algo mientras ocupo la CPU al 100%; también es esto útil en servidores web por ejemplo, y bajas frecuencias en ordenadores dedicados sólo a tareas muy pesadas. Ante la duda a 300Hz está bién.
La latencia a grandes rasgos es lo mismo no se por que hay dos opciones dedicadas a esto en la configuración del kernel la verdad, pero seguro que tiene un sentido jajaja. Low latency hace que se repartan mejor las tareas y una latencia alta que las tareas se terminen antes. Otra opción interesante es la compresión, no me extenderé mucho aquí, sólo decir que a mayor compresión antes se gargará el kernel en RAM, y tras ser descomprimido por el procesador, arrancará el pc, con muy poca compresión (o ninguna), el kernel tardará más en cargarse en RAM pero menos en ser descomprimido, por eso si tenéis una CPU de la hostia y unn hdd igual os interesa comprimirlo en lz4, pero si por el contrario tenéis un RAID de discos nvme, pues os la pela la compresión y le poéis que ninguna.
Bueno, ahora vamos a ir con los flags del kernel, estos no son opciones específicas para compilar un kernel, y se pueden aplicar a todo lo que uno compile. Los básicos para compilar un kernel serían los niveles de optimización y ajustar la arquitectura.
Para entender esto hace falta saber que es un compilador, y no es más que un software que interpreta el código de lo que se desea compilar, y lo convierte a código máquina, pero no siempre la traducción directa es la más eficiente para generar el código máquina, por ello los compiladores permiten distintos niveles de optimización, yo os voy a contar los de GCC, que es con lo que se suele compilar el kernel linux.
Otro flag interesante es el flag -march, que nos optimizará el binario a las optimizaciones de nuestra CPU, vendría siendo como esa chorrada que dicen de que apple hace un software para una máquina y por eso es tán eficiente, pero esto de verdad ;-)
Esto sólo es útil si váis a compilar un kernel para un sólo pc, ya que sólo irá para máquinas con los mismos juegos de instrucciones que la cpu para la que optimicéis (hasta donde sé no habría problema en optimizar para otra cpu que no sea la vuestra, si queréis que el binario sea para otra máquina).
La opción simple sería poner -march=native, pero esto no sirve si queremos compilar en red con distcc por ejemplo, o si queremos especificar otra máquina, por ello podemos poner la familia de nuestra CPU o la que sea, lo podéis buscar en google, no voy a poner la tabla aquí, pero aparece todo en la wiki de gentoo donde abajo os pondré el enlace.
Por último para acelerar la compilación y usar todos los núcles e hilos de nuestra CPU (esto no afectará al código generado), el flaj -j nos pormite ajustar los procesos que usará make para compilar el jernel, lo ideal sería poner el número de hilos que tenga nuestra CPU, pero si queremos hacer otras cosas mientras y se atasca el ordenador, o nos quedamos sin RM (cada proceso ocupa su RAM) podemos meter menos.
Un ejemplo de como kedaría nuestro comando para compilar recomendado sería: make -march=native -O2 -j8, si nuestra CPU es de 8 hilos claro.
Y esto sería todo, si crees que algo puede ser corregido o añadido azmelo saber, si no sabes quien soy desgraciadamente no podrás... Seguramente quien te haya pasado esto si sabrá quien soy, o conocerá a alquien que si me conocerá jajaja
Fuentes: