You are on page 1of 9

Cómo compilar el Kernel de Linux

Ajustar al máximo nuestro sistema con


un Kernel 2.6.x
Versión para imprimir

Linux nos permite acceder de forma libre a su código fuente, es decir, a las
instrucciones que componen el programa. Gracias a ello podemos compilarlo y crearnos
un Linux a medida, adaptándolo totalmente a las características de nuestra máquina.
Veamos cómo hacerlo con las últimas versiones del kernel.

La diferencia más importante entre los S.O. libres y los propietarios no es su coste, sino
la posibilidad de acceder de forma libre (y en la mayoría de los casos casi gratuita) a su
código fuente. En el caso de Linux, esto significa disponer de más de 18.000 ficheros
(entre los .c, ficheros de programa y .h, ficheros de cabecera) escritos en lenguajes C y
ensamblador. Bien, ¿y qué hago ahora que tengo todo esto en mi disco duro? ¿Cómo
recompilo el kernel? ¿Es esto algo que sólo mentes preclaras y programadores de
aspecto sospechoso pueden hacer? Como veremos, compilar el kernel está al alcance de
cualquiera que tenga ganas de aprender y motivación suficiente para disponer de un
S.O. personalizado en su máquina.

Montones de jerga, empezamos bien


Que nadie se asuste. Al menos, no tan pronto. Expliquemos un poco los términos
oscuros que hemos de emplear. Kernel, en inglés, es la parte sustancial de una cosa. En
el caso de un S.O. su kernel es la parte fundamental, la que inicia la máquina y nos da
los servicios imprescindibles. El kernel de Linux está programado en su mayoría en
lenguaje C, y algunas partes en ensamblador (lenguaje dependiente de la arquitectura de
cada máquina y el más cercano al código máquina).
Compilar el kernel no es más que construir un programa ejecutable a partir de su código
fuente. Es como hornear la harina con levadura para que nos salga pan. El código fuente
es al kernel lo que la harina al pan. Y una vez fuera del horno, el kernel es la miga y la
corteza, lo que hace pan al pan. El bloc de notas o el solitario (o en el caso del pan, si
lleva más o menos sal), no son fundamentales, luego no son el kernel.

Más sobre el kernel


Pero realmente ¿qué hace el kernel? Pues muchas cosas que normalmente no se ven,
pero sin las cuales sería casi imposible usar nuestras máquinas. Sin ánimo de ser
rigurosos (para eso recomiendamos el imprescindible libro de Andrew Tanembaum
Sistemas Operativos Modernos, cuyo índice se puede consultar en la página web del
sabio, www.cs.vu.nl/~ast/) el S.O. se ocupa de aislarnos del hardware real de nuestra
máquina y de ofrecernos servicios como la gestión de la memoria y de la CPU. Nos
aísla, por ejemplo, permitiendo que nuestro programa favorito de grabación de CD
funcione con cualquier grabadora, independientemente de su marca. Para ello se utiliza
un controlador de dispositivo o driver que se maneja siempre del mismo modo y oculta
las peculiaridades de cada grabadora. El S.O. gestiona la memoria y la CPU permitiendo
tener en ejecución simultáneamente varias tareas que no interfieran entre ellas. O bien
gestiona su comunicación mediante llamadas entre procesos.
¿Qué razones podemos tener para recompilar el kernel? Pueden ser varias, pero por citar
algunas: el kernel que viene con mi distribución no reconoce todo el hardware que tengo
instalado, o bien quiero aprovechar al máximo las características de mi máquina, o
quiero cargar sólo lo estrictamente necesario, eliminando drivers no usados, o quiero
aprender a compilar el kernel. Después de compilar nuestro primer kernel, miraremos a
Linux de otra forma: si hemos podido con esto, todo lo demás (en teoría, claro) es más
sencillo.

Obtener el kernel
Podemos obtener el kernel de Linux de diferentes fuentes (Internet, CD-ROM de
revistas como PC World, etc.). P
ara las versiones que deriven de Debian las dos fundamentales son la sede web oficial
del kernel de Linux, kernel.org, que podemos ver en la Figura 1, y los repositorios de
Debian (accesibles mediante las herramientas de bajo nivel apt-get y la aplicación de
alto nivel Synaptic). En Debian se distribuyen diferentes paquetes para el kernel, con
modificaciones especiales para Debian. Estos paquetes pueden corresponder a imágenes
de kernels ya compilados (listos para instalar), a los ficheros de cabecera de una versión
concreta (para desarrolladores o para recompilar un programa que los necesite) o bien
ser el árbol completo que contiene todos los fuentes del kernel. Los primeros se
llamarán kernel-image-*, los segundos kernel-headers-* y los últimos kernel-source-*.
La versión disponible a través de los repositorios Debian (incluyendo Sid, el repositorio
más actualizado de Debian) puede no ser la última. Normalmente transcurre un tiempo
hasta que se construye un paquete Debian y se prueba. En kernel.org dispondremos de
las últimas versiones, incluyendo las de prueba (que puede que no compilen
correctamente).
En nuestro caso vamos a usar el paquete Debian. Para ello, escogeremos la versión (con
Debian Sarge es la 2.8) y buscaremos en Synaptic el paquete correspondiente, llamado
kernel-source-2.6.8. Una vez descargado (ocupa algo más de 35 MB), veremos que ha
dejado un fichero en /usr/src llamado kernel-source-2.6.8.tar.bz2.
Antes de terminar con Synaptic, un par de notas sobre otros paquetes. Ya que tenemos
el kernel, antes de compilarlo debemos configurarlo. Para esto existen cuatro métodos:
sin interfaz gráfica, con una interfaz en modo texto, con una interfaz para X y con otra
especial para Gnome. Veremos el segundo y el último. Necesitaremos descargar, para la
configuración con menús texto, la biblioteca ncurses5 en su versión de desarrollo
(libncurses5-dev). Ojo con esto: probablemente tengamos instalada la biblioteca
libncurses5 y pensemos ¿y para qué se necesita una versión de desarrollo? Una
biblioteca permite usar sus funciones, pero no crear programas basados en ella. La
versión de desarrollo incluye la documentación de la biblioteca (en formato man), los
ficheros de cabecera y las tablas de símbolos, imprescindibles para que el compilador de
C pueda construir programas con ella.

Antes de empezar, copia de seguridad


Antes de hacer nada más, debemos advertir: instalar un nuevo kernel es algo que puede
ir mal. Y en ese caso puede que nuestra máquina no arranque. Para prevenir esto y
disponer de un método sencillo de restaurar el sistema, debemos hacer copia de
seguridad de nuestro kernel actual y de los módulos que estamos usando. Para ello,
abriremos una consola (pulsando con el botón derecho sobre el escritorio de Gnome y
seleccionando la primera opción) y nos convertiremos en root mediante:
$ su
Password:
# mkdir /root/backup-kernel
# cp -r /boot/ /root/backup-kernel/
# cp -r /lib/modules/2.6.5/ /root/backup-kernel/
Una vez realizada la copia de seguridad, continuaremos con la tranquilidad que da el
saber que si nuestro sistema no funciona correctamente, siempre podremos volver al
estado anterior de forma sencilla.
El kernel se distribuye comprimido en formato bzip2. Para descomprimirlo
escribiremos:
# cd /usr/src/
# bzip2 -d kernel-source-2.6.8.tar.bz2
Esto nos crea un fichero tar en /usr/src, concretamente kernel-source-2.6.8.tar. Este
fichero, que contiene todos los ficheros del kernel, no tiene actualmente permisos para
que lo lea o modifique un usuario normal. Vamos a extraerlo mediante:
# tar xvf kernel-source-2.6.8.tar
Veremos muchas líneas de información, una por cada fichero que se extrae del fichero
tar. Ahora nos cambiaremos a una consola de usuario normal. Esto es importante: los
pasos que hemos dado hasta ahora (descargar e instalar paquetes en el sistema, hacer
copia de seguridad de /boot y /lib/modules y desempaquetar el kernel) son acciones que
debe realizar root. Pero para recompilar el kernel no es preciso (ni quizás recomendable)
ser root. Cualquier usuario del sistema puede leer la carpeta con los fuentes del kernel,
pero no cambiarla (para impedir que un usuario pueda alterar el kernel en beneficio
propio). Por ello, vamos a crear una carpeta donde irán los ficheros intermedios de la
compilación y el fichero de configuración.
$ mkdir /home/dfreniche/Documentos/kernel-build
Una vez creada la carpeta, definiremos una variable de entorno que apunte a ella, para
ahorrar pulsaciones posteriores de teclas. A la hora de compilar el kernel podemos
indicar mediante la opción O=ruta-a-una-carpeta en qué carpeta queremos que se deje el
resultado de la compilación.
$ DIR_K=/home/dfreniche/Documentos/kernel-build/
$ echo $DIR_K
/home/dfreniche/Documentos/kernel-build/

Configurar el kernel
Ya estamos listos para comenzar con el trabajo serio. Lo primero es asegurarnos de que
no existen ficheros residuales de compilaciones antiguas o ficheros de configuración no
deseados. Para ello, la orden de “limpieza” es (en serio):
dfreniche@tesla:/usr/src/kernel-source-2.6.8$ make O=$DIR_K mrproper
CLEAN scripts/package
Ejecutaremos la primera herramienta de configuración que vamos a usar mediante:
dfreniche@tesla:/usr/src/kernel-source-2.6.8$ make O=$DIR_K menuconfig
Mientras se compila observaremos líneas de información como
HOSTCC scripts/lxdialog/yesno.o
HOSTLD scripts/lxdialog/lxdialog
que nos indican que se compila (CC) o enlaza (LD) alguna parte del código. Finalmente
obtendremos una pantalla como la de la Figura 2.
El manejo de esta herramienta es sencillo: con las teclas de cursor arriba y abajo
avanzamos por las opciones de menú. Las teclas de cursor derecha e izquierda cambian
la orden a ejecutar al pulsar Intro. Estas órdenes son Select (seleccionar), Exit (salir) y
Help (ayuda). Las opciones que en menuconfig aparecen con ---> son un submenú.
Entraremos en ellas marcando Select y pulsando Intro. Saldremos de estos submenús
seleccionando Exit y pulsando Intro.
¿Para qué utilizar esta versión del configurador aparentemente arcaica si disponemos de
otras más modernas? Puede ser que no dispongamos de Xwindow o que no arranquen y
necesitemos adaptar el kernel a un nuevo hardware. Igualmente, podemos disponer
únicamente de una conexión por terminal (telnet o ssh) como se da en servidores web
alojados en proveedores de acceso a Internet. Para estos casos (y para los nostálgicos)
nunca estará de más conocer la opción del menuconfig.
Al configurar el kernel de Linux podemos marcar algunas características para que estén
siempre activas. Otras, en cambio, no las querremos, por no disponer del hardware
asociado. Por último, algunas funcionalidades del kernel (especialmente los
controladores de dispositivos), nos interesarán a veces, y otras veces no (por ejemplo,
una tarjeta de red inalámbrica PC Card). Linux nos permite distinguir en la
configuración entre características integradas en una parte fija del kernel y otras que van
en módulos. Los módulos no son más que trozos del kernel que podemos cargar y
descargar de memoria a voluntad. Si tenemos cargados los módulos que habilitan
nuestra tarjeta de red, podremos conectarnos a Internet vía ADSL. Si el módulo no está
cargado, no podremos. Es casi igual que en otros sistemas propietarios, con la ventaja
de que podemos cargar y descargar módulos de memoria a nuestro antojo, sin necesidad
de reiniciar el sistema.
El objetivo de cualquier herramienta de configuración del kernel es obtener un fichero
llamado .config (el punto al inicio del nombre hace que sea un fichero oculto) que será
usado para determinar las características del nuevo kernel que vamos a compilar. Este
fichero se genera en la carpeta donde hemos decidido enviar el resultado de la
compilación ($DIR_K). Podemos reutilizar este fichero para siguientes versiones del
kernel, o para comenzar desde un estado ya conocido. Así, el trabajo duro será la
primera vez que compilemos el kernel.

Configurando el kernel con gconfig


Seguidamente, veamos la herramienta de configuración del kernel para Gnome. La
construiremos con la orden:
dfreniche@tesla:/usr/src/kernel-source-2.6.8$ make O=$DIR_K gconfig
Una vez compilada (puede que necesitemos instalar bibliotecas de desarrollo, como se
observa en la Figura 3) tendremos una pantalla como la de la Figura 4. Aquí los menús
se convierten en un árbol desplegable. Podemos seleccionar entre disponer de una
característica integrada en el nuevo kernel, no disponer de ella o tenerla como módulo
pulsando respectivamente con el ratón en Y, N o M. Las opciones posibles aparecen con
un subrayado.
La primera vez que se configura el kernel se pasará mucho tiempo leyendo la
descripción de las diferentes opciones. Hay que conocer el tipo de hardware que
tenemos instalado en la máquina (modelo de la tarjeta de vídeo, de red, de sonido, etc.).
Dar unas directrices generales para la configuración es algo temerario, pero las opciones
principales que debemos tener activas son:
Code Maturity Level Options (opciones de nivel de madurez del código): conviene
activarla, ya que a la hora de publicar el kernel pueden existir partes del mismo no
totalmente finalizadas por sus programadores, pero que den una cierta funcionalidad. Si
esta opción está activa, aparecerán estas opciones y las experimentales.
General Setup (configuración general): conviene activar el soporte de swap (para
disponer de memoria virtual), la comunicación entre procesos IPC, soporte para
dispositivos hotplug y acceso al fichero de configuración .config a través de /proc.
Loadable Module Support (soporte de módulos insertables): siempre activarla para una
máquina Linux que funcione en un PC de propósito general. Quizás se podría desactivar
para máquinas de propósito específico (un controlador industrial, un sistema empotrado,
etc.).
Processor Type and Architecture (tipo de procesador y arquitectura): debemos ajustarlo
a arquitectura PC compatible y seleccionar el modelo de procesador que tengamos. Si
seleccionamos un procesador inferior al nuestro, el kernel funcionará en ese modelo y
en todos los superiores, eso sí, sin aprovechar las características de nuestro modelo. Al
contrario (compilar para un procesador avanzado como Pentium 4 y ejecutar el kernel
en un i386) nos producirá un error del kernel. El resto de opciones por defecto pueden
ser adecuadas.
Power Management Options (opciones de gestión de consumo): existen dos estándares,
ACPI y APM. Debemos escoger ACPI siempre que nos sea posible (por ejemplo, si
nuestra máquina sólo soporta APM)
Bus Options (opciones de bus). Evidentemente debemos mantener soporte para PCI. Lo
que probablemente ya no necesitemos sea soporte para ISA (si nuestra placa no dispone
de slots de ese tipo) o MCA (¿alguien se acuerda de Micro Channel de IBM?). Si el
kernel es para un portátil debemos marcar el soporte de PCMCIA.
Executable file formats (formatos de ficheros ejecutables). Al igual que Windows
dispone de dos tipos de ejecutable distintos (.COM y .EXE), Linux dispone de un
formato antiguo de ejecutables (a.out) y el actual ELF. Si no disponemos de
aplicaciones compiladas en el formato antiguo nos bastará con soporte ELF.
Device Drivers (controladores de dispositivo). Esta es la parte más dura de la
configuración, ya que, dependiendo de lo que queramos soportar, debemos ir eligiendo.
Un consejo general: ante la duda es mejor marcar algo como módulo y compilarlo. Si
luego no lo necesitamos, siempre será más sencillo no cargarlo que tener que volver a
recompilar. Por eso, sobre todo las primeras veces, es mejor compilar “por exceso”.
File Systems (sistemas de ficheros). Los usuales serán ext2, ext3 (ambos para Linux),
msdos, vfat (FAT32) y ntfs para poder leer datos de particiones con las diferentes
particiones de Windows. Debemos activar también el soporte para el pseudo sistema de
ficheros /proc, en Pseudo Filesystems.
Kernel hacking. Opciones para depurar el kernel. Utilizar sólo si estamos desarrollando
código para el kernel.
Security Options (opciones de seguridad). Diferentes modelos de seguridad para el
kernel de Linux. Si dudamos, escogeremos el modelo por defecto (Default Linux
capabilities).
Criptographic Options. Soporte de diferentes rutinas de criptografía.
Library routines. Bibliotecas para ser usadas desde fuera del kernel. Se pueden activar
como módulos.
Tras configurar el kernel, grabaremos su configuración mediante el botón Save.
Podemos hacer copias con nombre diferente usando la opción File · Save As.
Finalmente saldremos de la configuración.

Compilar e instalar el kernel


Una vez tenemos configurado el kernel pasaremos a compilarlo mediante la orden make
bzImage. Ojo a la I, que es mayúscula y el resto minúsculas. El proceso llevará un rato y
un buen porcentaje de CPU, mostrando una pantalla como la de la Figura 5. Al final (si
no se han producido errores), en arch/i386/boot tendremos un fichero llamado bzImage
que es el kernel. Debemos instalarlo (copiarlo) en la carpeta /boot mediante cp
arch/i386/boot/bzImage /boot/vmlinuz-2.6.8. Para instalar el kernel hay que ser root.

Los módulos
Si hemos configurado alguna parte del kernel como módulos (lo cual siempre es
recomendable) debemos compilar ahora los módulos. Esto se hace con la orden make
modules. Si todo va bien, al finalizar la orden anterior debemos instalar los módulos
mediante make modules_install. Estas dos órdenes se pueden escribir como make
modules && make modules_install.
Al finalizar este proceso, dispondremos de los módulos recién compilados en
/lib/modules/`uname -r`/, es decir, en nuestro caso, en /lib/modules/2.6.8/

Configurar el arranque
Para que podamos probar el nuevo kernel, debemos editar el fichero que controla el
gestor de arranque, lilo.conf si usamos lilo, o bien /boot/grub/menu.lst en el cada día
más común caso de usar Grub. Lo mejor es duplicar una entrada que ya tengamos y
cambiar el title (es la descripción que aparece al arrancar Grub en cada opción) y la
entrada kernel, en nuestro caso dejándola como kernel /boot/vmlinuz-2.6.8.
title Guadalinex-2004
root (hd0,0)
kernel /boot/vmlinuz-2.6.8 root=/dev/hda1 vga=791
initrd /boot/initrd.splash

Reiniciar
Instalar un nuevo kernel es el único caso en el que resulta obligado reiniciar Linux. Si
instalásemos nuevos módulos no sería preciso reiniciar, ya que bastaría con cargarlos
(ver para ello modconf y modprobe). Tras reiniciar la máquina, si todo ha ido bien,
podemos comprobar que nuestro nuevo kernel se está ejecutando mediante uname -r,
comando que nos devolverá la versión de kernel activa.

Bibliotecas necesarias
--------------------------------
Para compilar los programas de configuración del kernel (menuconfig y gconfig)
necesitamos las bibliotecas:
libncurses5-dev (que a su vez puede solicitar la instalación de otras bibliotecas, lo cual
es normal), libatk1.0-dev, libexpat1-dev, libfontconfig1-dev, libfreetype6-dev,
libglade2-dev, libglib2.0-dev, libgtk2.0-dev libpango1.0-dev, libx11-dev, libxext-dev,
libxft-dev, libxi-dev, libxml2-dev, libxrender-dev, libxv-dev, render-dev, x-dev, xlibs-
static-dev, zlib1g-dev.
Para instalarlas, bastará con seleccionar libncurses5-dev y libglade2-dev. El sistema de
resolución de dependencias de Debian se encargará del resto.
¡El autor, el autor!
-------------------------
Aunque ya es una vieja historia, no por ello es menos excitante. El autor del primer
kernel de Linux es Linus Torvalds. Torvalds programó el primer kernel de Linux como
parte de su Proyecto fin de carrera, utilizando como guía el libro de Sistemas Operativos
de Tanembaum, pero creando un S.O. genuinamente distinto desde su inicio. Minix (el
S.O. analizado en el libro), funciona en cualquier procesador de la familia Intel 8086 y
compatibles y está construido como un microkernel. Linux, en cambio, es un kernel
monolítico y funcionaba inicialmente en procesadores Intel de 32 bits y superiores
(80386 y posteriores). Actualmente corre en un amplio rango de arquitecturas,
soportando un número creciente de CPU. Por estas y otras razones carecen de sentido
ciertas demandas sobre la autoría de Linux y si el código ha sido copiado de otros
UNIX.

Construyendo la documentación
----------------------------------------------
El kernel de Linux se distribuye junto con abundante documentación. Además del
fichero README (de obligada lectura) en la carpeta Documentation existen multitud
de documentos sobre diferentes aspectos. Incluso se distribuyen libros (principalmente
para desarrolladores del propio kernel) que podemos construir mediante las órdenes
(como root):
make pdfdocs
make htmldocs
make psdocs
Para ello debemos tener instalados unos paquetes (marcando docbook-utils el sistema de
dependencias marcará el resto para su instalación).

Reutilizar configuraciones
-------------------------------------
Configurar un kernel desde el principio puede ser frustrante. Por eso, nunca está de mas
comprobar si existe el fichero /proc/config.gz. El kernel es capaz de guardar la
configuración con la que fue compilado en este fichero comprimido. Bastará con
copiarlo a /usr/src/<carpeta-del-kernel>, descomprimirlo (mediante gzip -d config.gz) y
renombrar el fichero config a .config para poder usarlo. Al usar make gconfig
comenzaremos con la configuración del kernel que actualmente tenemos en ejecución.

Para impacientes
-------------------------
El proceso completo para compilar e instalar el kernel es:
tar cvfz /root/boot.tgz /boot
tar cvfz /root/modules-`uname -r`.tgz /lib/modules/`uname -r`
make mrproper
make gconfig
make bzImage
make modules
cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.8
make modules_install
¿Y SI ALGO FALLA?
---------------------------
Si por cualquier motivo nuestro sistema no arranca correctamente con el nuevo kernel
siempre podemos reiniciar con el antiguo y volver a compilar. Y en el peor de los casos,
como tenemos una copia de seguridad de /boot podemos recuperarla (como root)
mediante:
# cp -r /root/backup-kernel/ /boot/
# cp -r /root/backup-kernel/ /lib/modules/2.6.5/

Diego Freniche Brito es Consultor y Comunicador especializado en formación de


profesionales de T.I. e integración de Linux en diversos entornos. Comprometido con la
iniciativa Guadalinfo y con Guadalinex, actualmente tele-trabaja desde el Centro
Guadalinfo de El Saucejo.

You might also like