Renuncia de responsabilidad:
La versión original de este artículo fue publicada por IBM
developerWorks y es propiedad de Westtech Information Services. Este
documento es una versión actualizada del artículo original y contiene
mejoras introducidas por el Equipo de Documentación de Gentoo.
Este documento carece de soporte activo.
|
Compilar el núcleo Linux
1.
Introducción al núcleo
El núcleo es... ¡Linux!
¿Qué se piensa al oír la palabra "Linux"? Cuando la oigo, normalmente pienso en
una distribución de Linux completa y en todos los programas que hacen funcionar
esta distribución.
De todos modos, puede sorprendernos que, técnicamente, Linux sea un núcleo, y
nada más que un núcleo. Mientras que las otras partes a las que comúnmente
denominamos Linux (como el intérprete de comandos y el compilador) y que son
partes esenciales de cualquier distribución, están separadas técnicamente de
Linux (el núcleo). Mientras que mucha gente emplea el término "Linux" para
referirse a una "distribución basada en Linux", al menos todo el mundo podría
estar de acuerdo en que el núcleo Linux es el corazón de cada
distribución.
Definición de la gestión del hardware
El rol primario del núcleo Linux es gestionar directamente el hardware en el
sistema. El núcleo proporciona una capa de abstracción entre el hardware
en sí mismo y los programas de aplicaciones. De este modo, los programas no
necesitan saber los detalles acerca del conjunto de chips de la placa base o de
la controladora del disco -- pueden operar en un nivel superior en el que leen
y escriben archivos al disco en su lugar, por ejemplo.
Abstracción de la CPU
El núcleo Linux también proporciona un nivel de abstracción por encima de el
(los) procesador(es) en el sistema -- permitiendo a múltiples programas
aparentar ejecutarse al mismo tiempo. Linux hace esto permitiendo a varios
procesos UNIX ejecutarse al mismo tiempo -- y el núcleo se encarga de
proporcionar a cada uno un período de tiempo adecuado de el (los)
procesador(es).
Un núcleo Linux puede soportar una única CPU o múltiples CPUs -- y el núcleo
que estamos usando ahora está o bien capacitado para un solo procesador
(UP-aware) o bien está capacitado para el multiprocesamiento simétrico
(SMP-aware). Si tenemos una placa base con capacidad multiprocesador, pero
estamos usando un núcleo monoprocesador, ¡Linux no reconocerá ninguno de los
procesadores adicionales! Para resolver esto, tendríamos que compilar un núcleo
SMP adecuado para nuestro hardware. En la actualidad, los núcleos SMP funcionan
en sistemas con un solo procesador, aunque con una ligera pérdida de
rendimiento.
Abstracción de entradas/salidas (I/O)
El núcleo también maneja la muy necesaria tarea de abstraer todas las formas de
entrada y salida en ficheros. Imaginemos lo que ocurriría si cada programa
tuviera que manejar el hardware directamente -- si hubiésemos cambiado la
controladora de los discos, ¡todos los programas dejarían de funcionar!
Afortunadamente, el núcleo Linux sigue el modelo UNIX de proporcionar una
abstracción simple de entrada/salida al disco que todos los programas pueden
usar. De este modo, nuestra base de datos favorita no tiene que preocuparse de
si está almacenando los datos en un disco IDE, en una estructura RAID SCSI o en
un sistema de ficheros montado en red.
Central de comunicaciones en red
Una de las cosas que han llevado Linux a la fama es su robusta comunicación en
red, especialmente en el soporte TCP/IP. Si pensábamos que la pila de TCP/IP se
encuentra en el núcleo, ¡estábamos en lo cierto1 El núcleo proporciona una
buena interfaz de alto nivel para los programas que quieren enviar datos a
través de la red. Tras todo ello, el núcleo Linux gestiona directamente la
tarjeta de red o el módem, y maneja todos los detalles de bajo nivel de la
comunicación por internet.
Networking goodies
Una de las cosas más colosales acerca de Linux son todas las características
tan útiles que se encuentran en el núcleo, especialmente aquellas relacionadas
con las redes. Por ejemplo, se puede configurar un núcleo que permita a toda
nuestra red doméstica acceder a internet a través de nuestro módem Linux -- a
esto se le denomina enmascaramiento IP o IP NAT (traducción de la dirección de
red).
Adicionalmente, el núcleo Linux puede ser configurado para exportar o montar
sistemas de ficheros basados en la red como NFS, permitiendo a otras máquinas
UNIX de nuestra red de área local compartir datos con nuestro sistema Linux.
Arrancar, parte 1
Cuando ponemos en funcionamiento nuestro sistema basado en Linux, el núcleo se
carga desde el disco a la memoria por un gestor de arranque, como LILO. En este
momento, el núcleo toma el control del sistema. La primera cosa que hace es
detectar e inicializar todo el hardware que encuentra -- y que ha sido
compilado para soportar. Una vez que el hardware se inicializa adecuadamente,
ya está listo para ejecutar procesos. El primer proceso que ejecuta se denomina
init, que se encuentra en /sbin. Después, init
comienza otros procesos adicionales, según lo especificado en
/etc/inittab.
Arrancar, parte 2
init normalmente inicia varias copias de un programa llamado getty
, que aguarda a que ingresen usuarios desde la consola. Después de que
getty procese satisfactoriamente una solicitud de ingreso, se carga el
intérprete de comandos por defecto (el cual suele ser bash). Una vez que
nos encontramos en bash, tenemos el poder para lanzar cualquier programa que
nos apetezca.
Mientras todos estos nuevos procesos se inician, el núcleo lleva todo el
control, dividiendo cuidadosamente el tiempo de la CPU para que cada proceso
disponga de una parte adecuada del mismo. Además, el núcleo sigue
proporcionando la abstracción hardware y los servicios de red para todos los
procesos en ejecución.
Introducir... ¡módulos!
Todos las versiones de Linux recientes soportan módulos del núcleo. Los módulos
del núcleo son algo excelente -- son partes del núcleo que residen en el disco,
hasta que se necesiten. Tan pronto como el núcleo necesite la funcionalidad de
un determinado módulo, se carga desde el disco, se integra automáticamente en
el núcleo y está disponible para su uso. Además, si un módulo del núcleo no se
ha usado durante varios minutos, el núcleo puede voluntariamente descargarlo de
la memoria -- algo que se denomina "autolimpieza".
Módulos, parte dos
Los módulos del núcleo se encuentran en /lib/modules, y cada
módulo termina en .o ó .ko. Como es de suponer, cada
módulo representa un componente particular de una funcionalidad en el núcleo --
un módulo puede proporcionar soporte para el sistema de ficheros FAT, mientras
que otro puede proporcionar el soporte para una determinada tarjeta de red ISA.
Los módulos permiten que el núcleo ocupe muy poca memoria. Se puede crear un
núcleo que únicamente contenga las características indispensables para iniciar
nuestra computadora y que el resto de características se carguen bajo demanda
como módulos. Debido a que el núcleo limpia automáticamente todos los módulos
que carga, se puede poner bajo buen uso la memoria del sistema.
Módulos -- ¡cosas importantes!
No se puede poner todo en módulos. Debido a que los módulos se almacenan
en el disco, la imagen de inicio del núcleo necesita tener integrado el soporte
para la controladora de discos, así como para el sistema de ficheros nativo
(normalmente el sistema de ficheros ext2). Si no se dispone de esos componentes
esenciales integrados en la imagen del núcleo (y se encuentran compilados como
módulos en su lugar), entonces el núcleo no estará capacitado para cargar esos
módulos desde el disco -- creando el desagradable problema del huevo o la
gallina.
2.
Localizar y descargar el código fuente
Versiones del núcleo
Para compilar un núcleo reciente, se necesita descargar el código fuente
primero. Pero antes de descargar el código fuente del núcleo, necesitamos saber
qué es lo que estamos buscando exactamente. La primera pregunta que hay que
hacerse es -- ¿queremos usar un núcleo estable o experimental?
Los núcleos estables siempre tienen un segundo dígito par -- por ejemplo,
2.0.38, 2.2.15, 2.2.18, y 2.4.1 se consideran todos ellos núcleos "estables"
(debido al 0, 2, 2 y el 4, respectivamente). Si se quieren hacer pruebas con un
núcleo experimental, normalmente se buscará aquel cuyo número sea mayor y que
tenga un segundo dígito impar. Por ejemplo, 2.3.99 y 2.1.38 son ambos núcleos
experimentales (debido al 3 y al 1, respectivamente).
Historia de la versión del núcleo
La serie 2.2 se considera una versión moderna y estable del núcleo. Si
"moderna" y "estable" son cosas que nos suenan bien, hay que buscar el núcleo
2.2 con el tercer número lo más elevado posible (2.2.16 es la versión más
reciente en este momento).
Mientras se estaba desarrollando la serie 2.2 del núcleo, se comenzó a trabajar
en la serie 2.3. Esta serie se creó como campo de pruebas para nuevas y
avanzadas características que posiblemente aparecerían en la serie 2.4 estable.
En este momento, se ha alcanzado la versión 2.3.99 y el desarrollo de la serie
2.3 se ha detenido. Estos días, los desarrolladores están trabajando en obtener
la serie test de los núcleos 2.4.0. Si nos gusta vivir al límite
deberíamos probar la versión 2.4.0-test más reciente que podamos obtener.
Aviso con respecto al núcleo 2.4
Una vez que se libere un núcleo 2.4 real (como el 2.4.0), no hay que
asumir que dicho núcleo se encuentre listo para sistemas con una misión crítica
como los servidores. A pesar de que la serie 2.4 se supone que será estable, es
muy probable que los primeros núcleos 2.4 necesiten aún algo de depuración.
Como suele ocurrir en la informática, la primera versión de algo puede contener
errores muy importantes. Mientras que esto no tiene porqué suponer ningún
problemam si estamos probando un núcleo en nuestra estación de trabajo
doméstica, es un riesgo que se debe evitar cuando nuestra máquina proporciona
servicios valiosos para otros.
Descargar el núcleo
Si sólamente se desea compilar una nueva versión del núcleo que ya tenemos
instalado (para habilitar el soporte SMP, por ejemplo), entonces la descarga no
es necesaria -- se puede evitar esta sección y la siguiente si es el caso.
Se pueden encontrar núcleos en http://www.kernel.org/pub/linux/kernel
. Cuando accedemos a este sitio, encontraremos el código fuente del
núcleo organizado en diferentes directorios, basados en la versión del núcleo
(v2.2, v2.3, etc.) Dentro de cada directorio encontraremos archivos con la
etiqueta "linux-x.y.z.tar.gz". Éstos son los de código fuente del
núcleo. También pueden verse archivos etiquetados como "patch-x.y.z.gz
" y "patch-x.y.z.bz2". Estos archivos son parches que
pueden usarse para actualizar la versión anterior del código fuente del núcleo.
Si se quiere compilar una nueva versión del núcleo, será necesario descargar
uno de los archivos "linux".
Desempaquetar el núcleo
Si se ha descargado un nuevo núcleo desde kernel.org, ha llegado el momento de
descomprimirlo. Para ello, hacemos un cd a /usr/src. Si
encontramos ahí un directorio con el nombre linux, entonces lo
movemos a linux.old (mv linux linux.old, como superusuario
o administrador).
Ahora es el momento de extraer el nuevo núcleo. Mientras seguimos en
/usr/src, tecleamos:
Listado de Código 2.1: Extracción con gzip |
# tar -xzvf /path/to/my/kernel-x.y.z.tar.gz
|
o
Listado de Código 2.2: Extracción con bzip2 |
# tar -xvjf /path/to/my/kernel-x.y.z.tar.bz2
|
Dependiendo de si el código fuente se encuentra comprimido con gzip o
bzip2. Después de teclear ésto, nuestro nuevo código fuente del núcleo
se encontrará en el nuevo directorio linux. Hay que tener cuidado:
¡todo el código fuente del núcleo ocupa más de 50 megabytes en el disco!
3.
Configuración del núcleo
Hablemos acerca de la configuración
Antes de compilar el núcleo, es necesario configurarlo. La configuración nos
proporciona la oportunidad de controlar exactamente las características que
queremos habilitar (y deshabilitar) en nuestro nuevo núcleo. También podemos
controlar las partes que se compilan integradas en la imagen binaria del núcleo
(que se carga al inicio), y las partes que se cargan bajo demanda en módulos
del núcleo.
La antigua forma de configurar el núcleo era tremendamente costosa, consistía
en entrar en /usr/src/linux y teclear make config. A pesar
de que make config todavía funciona, por favor, no utilizar este método
para configurar el núcleo -- a menos que nos guste responder a cientos (sí, sí,
¡cientos!) de preguntas sí/no en la línea de comandos.
La nueva forma de configurar
Nosotros, que somos algo más actuales, en lugar de teclear make config,
o bien tecleamos make menuconfig o make xconfig. Si se desea
configurar el núcleo, tecleamos una de estas dos opciones. Si tecleamos make
menuconfig obtendremos un bonito sistema por menús basado en texto que
podremos usar para configurar el núcleo, mientras que si tecleamos make
xconfig obtendremos una bonita interfaz gráfica de usuario basada en X para
configurar las características del núcleo. He aquí una captura de make
menuconfig:
Ilustración 3.1: menuconfig en acción |
 |
Cuando se usa make menuconfig, las opciones que tienen un < >
a su izquierda pueden ser compiladas como módulos. Cuando la opción se
encuentra resaltada, presionar la barra espaciadora para elegir si la opción
no está seleccionada (< >), seleccionada para estar integrada en
la imagen del núcleo (<*>) o seleccionada para ser compilada como
módulo (<M>).
Trucos de configuración
Hay muchísimas opciones en el núcleo, y no disponemos del lugar suficiente para
explicarlas aquí -- por lo que, por favor, recomiendo hacer uso de la ayuda
proporcionada por el propio núcleo. Todas las opciones están explicadas con
mayor o menor detalle y cada una, normalmente, incluye la frase "If you don't
know what this means, type Y (or N)." (si no se sabe lo que ésto significa,
teclear Sí (o No)). Estos consejos nos ayudan a evitar problemas en caso de no
saber lo que una opción hace en concreto. Para acceder a la ayuda, resaltamos
la opción sobre la que tenemos dudas y presionamos la tecla "?".
4.
Compilar e instalar el núcleo
make dep; make clean
A una vez que hemos configurado el núcleo, llega el momento de compilarlo.
Antes de que podamos compilarlo, necesitamos generar la información de las
dependencias y limpiar cualquier "vestigio de compilación" antiguo. Lo cual se
consigue tras teclear make dep; make clean mientras nos encontramos en
/usr/src/linux.
Make bzImage
Ahora es el momento de compilar la imagen binaria del núcleo. Tecleamos make
bzImage. Después de varios minutos, la compilación habrá culminado y
encontraremos el archivo bzImage en /usr/src/linux/arch/i386/boot
(para un núcleo x86 PC). Mostraremos cómo instalar la nueva imagen del núcleo
en un momento, pero ahora es el momento de los módulos.
Compilar los módulos
Ahora que hemos creado la bzImage, es el momento de compilar los módulos.
Aunque no se haya habilitado ni un solo módulo cuando se configuró el núcleo,
este paso no debe evitarse -- es bueno adquirir el hábito de compilar los
módulos inmediatamente después de una bzImage. Dado que si realmente no se
tiene ningún módulo que compilar, este paso se lleva a cabo rápidamente.
Tecleamos make modules; make modules_install. Lo cual da lugar a que los
módulos se compilen y se instalen en /usr/lib/<kernelversion>
.
¡Enhorabuena! Nuestro núcleo se encuentra compilado por completo y los módulos
están compilados e instalados. Ahora es el momento de reconfigurar LILO para
que pueda iniciar el nuevo núcleo.
5.
Configuración del inicio
Introducción a LILO
Ha llegado, finalmente el momento de reconfigurar LILO para que pueda cargar el
nuevo núcleo. Linux es el gestor de arranque Linux más extendido, y se usa en
todas las distribuciones Linux. Lo primero que debemos hacer es echar un
vistazo al archivo /etc/lilo.conf. Contendrá una línea que incluya
image=/vmlinuz. Esta línea le indica a LILO dónde encontrar el núcleo.
Configuración del inicio, parte 2
Para configurar LILO para que inicie el nuevo núcleo, tenemos dos opciones. La
primera es sobre-escribir el núcleo que estamos usando -- lo cual es muy
arriesgado si no se dispone de ningún método de inicio de emergencia, como un
disco de inicio con dicho núcleo en el mismo.
La opción más segura es configurar LILO para que pueda iniciar tanto la versión
nueva como la antigua del núcleo. LILO puede configurarse para que inicie el
nuevo núcleo por defecto, pero proporcionando una forma de seleccionar el
antiguo en caso de encontrar problemas. Esta es la opción recomendada y la que
mostraré cómo realizar.
Configuración del inicio, parte 3
Nuestro lilo.conf puede ser similar a este:
Listado de Código 5.1: /etc/lilo.conf |
boot=/dev/hda
delay=20
vga=normal
root=/dev/hda1
read-only
image=/vmlinuz
label=linux
|
Para añadir una nueva entrada de inicio a lilo.conf, hacemos lo
siguiente. Primero, copiamos /usr/src/linux/arch/i386/boot/bzImage
a un archivo en nuestra partición raíz, como /vmlinuz2.
To add a new boot entry to your lilo.conf, do the following.
First, copy /usr/src/linux/arch/i386/boot/bzImage to a file on
your root partition, such as /vmlinuz2. Una vez allí, duplicamos
las tres últimas líneas de nuestro lilo.conf y las añadimos de
nuevo al final del archivo... Casi hemos llegado...
Configuración del inicio, parte 4
Ahora, nuestro lilo.conf debería ser semejante a este:
Listado de Código 5.2: el nuevo lilo.conf |
boot=/dev/hda
delay=20
vga=normal
root=/dev/hda1
read-only
image=/vmlinuz
label=linux
image=/vmlinuz
label=linux
|
Ahora, cambiamos la primera línea image= para que indique
image=/vmlinuz2. Después cambiamos la segunda línea label=
para que indique label=oldlinux. También es necesario asegurarse de que
hay una línea delay=20 al comienzo del archivo -- de no haberla, se
añade una. De haberla hay que confirmar que el número es 20 por lo menos.
Configuración del inicio, parte 5
El archivo lilo.conf definitivo será muy semejante a este:
Listado de Código 5.3: El lilo.conf final |
boot=/dev/hda
delay=20
vga=normal
root=/dev/hda1
read-only
image=/vmlinuz2
label=linux
image=/vmlinuz
label=oldlinux
|
Después de hacer todo esto, necesitaremos ejecutar lilo como
superusuario. ¡Lo cual es muy importante! Si no lo hacemos el proceso de inicio
no funcionará. Ejecutando lilo damos la oportunidad de que actualice su
mapa de inicio.
Explicación de la configuración de inicio
Expliquemos ahora todos nuestros cambios. Este archivo lilo.conf
fue configurado para permitirnos iniciar dos núcleos diferentes. Nos permite
iniciar nuestro núcleo original, localizado en /vmlinuz. También
nos permitirá iniciar nuestro nuevo núcleo, localizado en /vmlinuz2
. Por defecto, intentará iniciar el nuevo núcleo (debido a que las
líneas image/label para el nuevo núcleo aparecen primero en el archivo de
configuración).
Si, por cualquier circunstancia, se necesita iniciar el núcleo anterior,
sencillamente reiniciamos la computadora y presionamos la tecla de mayúsculas.
LILO lo detectará y nos permitirá teclear la etiqueta de la imagen que deseamos
iniciar. Para iniciar nuestro viejo núcleo teclearíamos oldlinux y
pulsaríamos intro. Para ver una lista con todas las posibles etiquetas, hay que
pulsar TAB.
6.
Recursos
¡Enhorabuena por la compilación de nuestro propio núcleo! Espero que todo
funcionase bien. He aquí algunos recursos donde se puede aprender más acerca de
la compilación del núcleo:
-
El
Kernel-Como es otro buen recurso para obtener instrucciones acerca de
la compilación del núcleo.
-
www.kernel.org, el sitio que
contiene los archivos del núcleo Linux.
|