Linux
 
Compilando el Kernel de Linux

- Introducción

     Se denomina kernel al "núcleo" de todo sistema operativo, es quien maneja las entradas y salidas, la memoria de las tareas y los procesos que se estan ejecutando. Dicho núcleo permite que el software se abstraiga de la comunicación con el hardware del ordenador y en esta forma los desarrolladores de programas no tienen que ocuparse de como se comunica su programa en forma directa con el hard del equipo sobre el cual va a correr. El kernel de todo sistema Linux es lo que inicialmente recibió el nombre de "Linux". Cuando en 1991 Linus Torvalds dio a luz su sistema operativo, lo que él en realidad tenía entre manos era un kernel que manejaba algún hardware de ordenadores x86. Todo el software agregado sobre el kernel (shells, aplicaciones para consola, editores de texto, XFree, KDE, Gnome, etc) forma en conjunto con éste lo que hoy conocemos como distribuciones. La mayor parte del software que viene en estas distribuciones es desarrollado bajo los auspicios de la FSF (Free Software Foundation) dentro del proyecto GNU que prevee la libre distribución del código de dichos programas. Por ello el nombre correcto del sistema operativo del que trata este sitio es GNU/Linux, pero por comodidad todo mundo lo referencia como Linux.

     Linux permite que retoquemos su parte más básica, la que interacciona con el hardware, recompilando su kernel para adecuarlo a nuestros dispositivos y necesidades.

     El kernel por defecto que viene con las distribuciones estándar, generalmente es uno que trae soporte para mucho hardware y software del cual no disponemos y muy probablemente que nunca usaremos, asi como las opciones genéricas que aseguran un funcionamiento sin complicaciones en casi todo el extenso parque de hardware x86. Si usted puede compilar su kernel y afinarlo para su sistema en particular, muy probablemente tenga arranques más rápidos, menor uso de memoria y aplicaciones más optimizadas. Sin embargo muchas veces se optimiza tanto que ciertas cosas dejan de funcionar :).

     Por ello, en este artículo veremos la compilación en detalle y como probar el kernel compilado con la posibilidad de volver a la versión estable que nos hallabamos utilizando hasta el momento por si algo sale mal; (en honor a la verdad es muy probable que su primera compilación sea un fiasco y que su primer kernel resulte tan operativo como el cerebro de Frankenstein; quien escribe estas líneas compiló 6 veces un kernel 2.2.14 antes de obtener uno que funcionase). Luego de esta breve introducción, manos a la obra entonces.

- Obteniendo el kernel e instalándolo

     Si usted instaló su linux desde un cd de una distribución en particular (Red Hat, SuSE, Debian, etc) seguramente los sources del kernel están incluídos con él y muy posiblemente se hallan instalados en el directorio /usr/src/linux (ubicación por defecto). Si no se encontrase instalado lo podremos agregar desde el cd mediante el manejador de paquetes (por lo general será un .rpm o un .deb). Este kernel es, obviamente la misma versión que corre actualmente su Linux-Box. Sin embargo, usted puede ir más lejos, y aprovechando el empujón, conseguir los sources de una versión más reciente del kernel.

     Para ello terminaremos seguramente en www.kernel.org. De éste sitio se pueden descargar las últimas versiones del kernel, pero están disponibles todas. Las diferentes versiones del kernel de Linux se enumeran de la siguiente forma:

Numeración de versiones

     El "release number" es el primer identificador mayor, un cambio en él demuestra un avance mayor; "version number" par indica una versión estable y oficial, un número impar aquí nos indica una versión experimental y muy probablemente con mayor inestabilidad. "Patch level" refleja mejoras menores y corrección de bugs. Cronológicamente luego de los kernels 2.0 siguen los 2.2 y luego los 2.4; las versiones impares no se suelen considerar. Salvo que usted sea un gurú de Linux o sepa bien lo que está haciendo, no querrá compilar una versión que pueda contener partes experimentales o inestables, por ello recomiendo conseguir un kernel par.

     Una vez con los fuentes del kernel en el disco (los cuales vienen generalemente en formato .tgz o .tar.gz), procederemos a descomprimirlos y desempaquetarlos en el directorio /usr/src/linux-x.xx.x, donde x.xx.x es la versión de dicho kernel. Ya estas tareas necesitan de los privilegios de root para ejecutarse, si aún no le hemos hecho deberíamos adquirir la personalidad de root con:

# su root

o bien loguearnos en una terminal como root. Hecho esto, procederemos a descomprimir y desempaquetar:

# gzip -d linux-x.xx.x.tar.gz
# tar -xvf linux-x.xx.x.tar -C /usr/src

     Merced a que el programa tar incluye la opción de descomprimir archivos en formato gzip, dichas operaciones se pueden realizar en un solo paso con:

# tar -zxvf linux-x.xx.x.tar -C /usr/src

     Luego, si el kernel se desempaquetó en un directorio linux-x.xx.x haremos un link simbólico desde /usr/src/linux a /usr/src/linux-x.xx.x:

# ln -s /usr/src/linux-x.xx.x /usr/src/linux

     Seguidamente nos situamos en dicho directorio:

# cd /usr/src/linux

- Configurando las opciones

     Aquí tenemos tres utilitarios para configurar los parámetros que serán incluidos en nuestro kernel:

# make config
# make menuconfig
# make xconfig

     La primera forma nos presentará un conjunto de preguntas en la línea de comandos acerca de las opciones con las cuales queremos compilar nuestro kernel, la segunda es una especie de GUI desde la consola, y la tercera opción es una interfaz que corre únicamente desde una terminal iniciada adentro de las X-Window.

     En este artículo podemos ver imágenes de las dos ultimas utilidades de configuración, por ser las que realmente vale la pena usar. La primera opción, de ir contestando preguntas en la línea de comandos, tiene la terrible falencia de que una equivocación requiere como corrección comenzar nuevamente la configuración. Este método es realmente tétrico y no se recomienda salvo casos desesperados.

make xconfig

Aspecto de make xconfig

make menuconfig

Aspecto de make menuconfig

     Si usted no dispone de X-Window instalado, entonces su elección es make menuconfig. En la primera pantalla de ambas herramientas, xconfig o de menuconfig, se muestran las principales áreas de soporte para dispositivos. Dentro de cada una de ellas se hallan cada una de las opciones, que muestran generalmente tres posibilidades:

Y= se incluirá soporte en el kernel para este ítem
N= no se incluirá en el kernel
M= se incluirá en forma de módulo

     Incluir algo en el kernel en forma modular significa que el soporte se compila en el kernel pero que la parte de software para dicho ítem se compila en un "módulo" separado que el kernel mismo se ocupará de cargar en memoria solo cuando necesite el soporte para dicho ítem. Afortunadamente de la mayor parte de las opciones existe información de ayuda que nos puede despejar dudas sobre lo que significa dicha opción y en que casos es necesario compilarla según el uso de la máquina a la cual va destinado el kernel que estamos armando.

     Todo lo que se compila en el kernel permanece en memoria siempre, las partes compiladas en forma modular solo se cargan en memoria cuando son requeridas por el sistema pudiendose luego "bajar" en el momento en que ya no se utilizan.

     NOTA IMPORTANTE: antes de ejecutar la herramienta par compilar hay que correr el comando:

# make mrproper

que limpia posibles restos de configuraciones anteriores que pueden hacer que la generación de nuestro núcleo sea fallida. Si acabamos de instalar las fuentes del kernel del CD de la distribución o las bajamos de internet, es evidente que este procedimiento no es necesario, pero cuando necesite volver a compilar con dichas fuentes es imprescindible "limpiar" antes de operar.

- Principales Opciones

     Es imposible darle un repaso a todas los aspectos de configuración del kernel, además la ayuda que viene built in con él es bastante explicativa, sin embargo podemos dar algunos tips en los principales apartados. Generalmente las opciones que aparecen ya seleccionadas por defecto brindan un funcionamiento seguro, por ello ante la duda podemos dejar ciertos items por defecto.

     En "Processor type and features" elegiremos el microprocesador de que disponga nuestra máquina; eligiendo 386 correrá en cualquier micro superior pero no estará optimizado, si seleccionamos pentium o pentium pro (opción también válida para la línea de compatibles K5 yK6) entonces no correría en 386, 486 ni 586 pero aprovecharíamos las características avanzadas de micros superiores. Bajo "Block devices" se especificarán los drivers para las unidades de almacenamiento que se hallan en nuestro ordenador. "Filesystems" define los sistemas de archivos a los cuales podremos acceder. "Networking options" contiene los protocolos que soportará nuestro linux, aqui deshabilitaremos aquellos que estemos seguros de no utilizar y activaremos, por ejemplo, ppp si nos vamos a conectar a Internet via módem, TCP/IP es aqui elección obligada. "SCSI support" contiene las opciones de dispositivos SCSI, obviamente útiles para aquellos con sistemas con dichas interfaces o quienes teniendo un sistema IDE poseen una grabadora que piensan utilizar para grabar CD's y no como simple lectora o que tienen zip's paralelos. "Network device support" se ocupa del apartado de las placas de red. "Sound" hace lo propio con las interfaces de sonido. "Character devices" configura los puertos serie, el puerto paralelo, y el mouse entre otros. "Loadable module support" permite que carguemos soporte modular para algunos dispositivos, obligatorio si utilizaremos módulos.

Apartado Block devices

     Una vez finalizada la elección del soporte, elegiremos save and exit para salir de la herramienta y salvar los cambios (registrados en el archivo /usr/src/linux/.config). También existe la posibilidad de guardar la configuración en un archivo alternativo o cargar una configuración anterior desde un archivo ya existente.

En la imagen de la izquierda podemos ver las primeras secciones del aparatado Block devices en la herramienta xconfig. La ayuda de cada opción, accesible con el botón Help de la derecha proporciona en la mayor parte de los casos suficiente información para decidir si añadir o no dicho soporte.

- Compilando

     Ahora, encontrándonos en el directorio /usr/src/linux tipearemos:

# make dep
# make clean

estos comandos chequean dependencias y preparan los sources para la compilación. Luego de finalizada esta fase sin errores (la pantalla se llena de verborragicas líneas de mensajes, si ocurriese algún error make nos informará); compilaremos el kernel mediante:

# make bzImage

     Esta tarea puede tardar varios minutos a varias horas dependiendo de la máquina en la cual lo estemos ejecutando (otra vez tendremos los mensajes satánicos en pantalla). Luego si todo fue bien podremos contemplar el kernel recién generado en el archivo bzImage en el directorio /usr/src/linux/arch/i386/boot. Este kernel lo copiaremos al directorio /boot.

     Antaño se utilizaba el comando:

# make zImage

para generar la imagen, pero esto indefectiblemente fallaba cuando el archivo obtenido superaba los 500 kb aproximadamente. Actualmente un kernel estándar ocupa no menos de 600 kb por lo cual esta forma de generación ha caído en desuso.

- Preparando la carga del nuevo kernel

     Lo que sigue es configurar LILO para que arranque el sistema con este nuevo kernel recién generado. Con dicho kernel ya copiado en /boot, abriremos el archivo /etc/lilo.conf mediante cualquier editor de texto y crearemos una nueva sección "image" para que lo cargue. En nuestro caso es la sección que comienza con image=/boot/bzImage y cuya etiqueta es linux-nuevo. Un ejemplo de lilo.conf con dos entradas para arrancar Linux en la tercera partición del disco IDE primario master sería similar al que sigue a continuación:

# LILO configuration file
append="vga=0x0301"
boot=/dev/hda3
vga = normal
read-only
prompt
timeout=100
image = /boot/vmlinuz
root = /dev/hda3
label = linux
image = /boot/bzImage
root = /dev/hda3
label = linux-nuevo

     

     Como hemos puesto la nueva sección por debajo de la original, se cargará por defecto la que veníamos usando y deberemos tipear "linux-nuevo" en el prompt de LILO para cargar la nueva. Si todo va bien y no tenemos problemas en el booteo ni usando nuestro Linux con su nuevo kernel, entonces luego podremos invertir el orden de ambas "ïmages" en /etc/lilo.conf con lo cual el arranque se realizará por defecto con el flamante kernel.

     Luego de editar el archivo /etc/lilo.conf deberemos ejecutar:

# /sbin/lilo

para que LILO lea la nueva configuración y se actualize.

- Generando los módulos

     Una vez con el kernel en su lugar y listo para cargarse en el próximo arranque de la máquina, deberemos generar los módulos, partes que se van a cargar en memoria solo cuando el kernel lo solicite. Los módulos suelen residir en el directorio /lib/modules/x.xx.xx, donde x.xx.xx es la versión de kernel que actualmente empleamos. Si estamos compilando la misma versión de kernel al generar los módulos es posible que sobreescribamos algunos de ellos (porque se instalan por defecto en /lib/modules/x.xx.xx), razón por la cual es conveniente mover el directorio actual a otro que se llame x.xx.xx-old, por ejemplo. Esto mediante:

# mv /lib/modules/x.xx.xx /lib/modules/x.xx.xx-old

     Ahora, tomada ya esta precaución podemos generar los módulos. Con este fin ejecutaremos, situados en /usr/src/linux:

# make modules
# make modules_install

     Con esto se crearán los módulos e instalarán en el directorio /lib/modules/x.xx.xx. Luego nos movemos a este directorio y correremos:

# cd /lib/modules/x.xx.xx
# depmod -a

lo cual creará una lista de las dependencias de los módulos y el orden de carga de los mismos. Un archivo llamado modules.dep se generará en dicho directorio con esta información.

- Reboteando la máquina para probar el kernel

     Ahora es tiempo de hacer un reboot de nuestra Linux-Box y probar el nuevo kernel. Una vez presentado el prompt de LILO, pulsando tab veremos las opciones que tenemos para arrancar, una de las cuales debería ser "linux-nuevo". La seleccionamos tipeándola y listo: ya nos encontramos corriendo nuestro nuevo kernel.

 

Ultima actualización: 16-Mar-2008