Anuncios

ANUNCIOS PATROCINADOS

COMO CONFIGURAR EL KERNEL DE LINUX

Leave a Comment

Manual tomado de aqui


La compilación del kernel es un tema sobre el que ya hay muchos tutoriales, pero puesto que alguna vez se ha pedido en los comentarios[1], voy a intentar hacer un resumen sobre cómo lo suelo hacer yo en mis Debian.

¿Por qué podemos querer compilar el kernel? Pues normalmente porque tengamos algún hardware que no esté soportado por el kernel estándar de la distribución (por ejemplo, en este blog, lo hemos usado mucho cuando hablábamos de compilar los drivers gráficos para los chipsets de las VIA EPIA) o porque haya alguna aplicación que necesite crear módulos del kernel para poder trabajar, como por ejemplo el VMWare o el kqemu. En Cómo mantener los acentos y las eñes al montar NTFS, FAT o smbfs y al compartir directorios con Samba también lo usamos para modificar el juego de caracteres a usar por defecto. Hace poco, en Probando la netconsole de Linux, también nos hizo falta recompilarlo, así como en Solucionando el error “attempt to access beyond end of device” con reglas de udev, hal y/o un parche del kernel y en Hibernación en Linux con TuxOnIce. Notas sobre los initrd y sobre cpio.

La mayoría de las distribuciones esperan que se compile e instale el kernel con sus herramientas específicas. En el caso de Debian y Ubuntu, normalmente con la herramienta make-kpkg del paquete kernel-package, como podemos leer en:

Y de hecho, las distribuciones ya suelen llevar sus fuentes del kernel preparadas a su medida:

# apt-cache search linux-source
linux-patch-debian-2.6.22 - Debian patches to version 2.6.22 of the Linux kernel
linux-source-2.6.22 - Linux kernel source for version 2.6.22 with Debian patches
linux-tree-2.6.22 - Linux kernel source tree for building Debian kernel images

Sin embargo yo, como buen abuelo cebolleta de Linux, sigo haciéndolo como lo he hecho toda la vida, de una forma totalmente independientemente de la distribución usada.

Lo primero es descargar el kernel deseado de www.kernel.org. Los kernels disponibles en este sitio son denominados vanilla kernels, indicando con este nombre que son puros en el sentido de que son tal cual los desarrolladores del kernel los han liberado. Posteriormente las distribuciones suelen distribuir kernels parcheados para añadir funcionalidades que no existen en el kernel vanilla (por ejemplo, el bootsplash o la hibernación con TuxOnIce) o para añadir soporte a hardware que no está aún soportado. No es raro ver en las listas de distribución de proyectos que incluyen parches del kernel que antes de permitirte abrir un bug te pidan que pruebes con un parche vanilla para descartar que los parches de tu distribución estén causando el comportamiento indeseado.

En el momento de escribir estas líneas, la última versión estable del kernel es la 2.6.23.9 (unos 43MB comprimida en bz2), así que vamos a por ella:

# wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.23.9.tar.bz2
[...]

Vamos a /usr/src/, la descomprimimos allí, hacemos un enlace simbólico para que /usr/src/linux nos lleve a las fuentes de nuestro nuevo kernel y entramos:

# cd /usr/src/
# tar xvfj /root/SW/linux-2.6.23.9.tar.bz2
[...]
# ln -s -n -f linux-2.6.23.9 linux
# cd linux

Estamos ahora ante las fuentes de un kernel totalmente limpito. Ni siquiera tiene una configuración en el fichero .config, que es donde se guardará nuestra configuración. Si en algún momento tras nuestras pruebas queremos volver a exactamente este punto, sólo tenemos que ejecutar un “make mrproper” y las fuentes volverán a estar exactamente igual que ahora a menos que se haya aplicado algún parche.

No debemos dejar de leer el fichero README que nos cuénta cómo compilar el kernel. Además, en el subdirectorio Documentation hay infinidad de ficheros de ayuda que nos pueden aclarar las ideas en multitud de cuestiones relativas a distintos apartados del kernel.

Pues bien, aquí podemos hacer un “make config“, que nos preguntará elemento por elemento si lo queremos incluir o no (o si lo queremos integrado en el kernel o como módulo):

# make config
scripts/kconfig/conf arch/x86_64/Kconfig
*
* Linux Kernel Configuration
*
*
* General setup
*
Prompt for development and/or incomplete code/drivers (EXPERIMENTAL) [Y/n/?]

Pero esto es muy pesado, así que indudablemente, es mucho mejor si lo hacemos con alguno de los interfaces de usuario que tenemos a nuestra disposición. Yo personalmente no me aclaro bien con otro que no sea el del “make menuconfig“, basado en ncurses (necesitamos el paquete libncurses5-dev para que funcione):

make menuconfig

Pero si tenemos las librerías QT también podemos hacer un “make xconfig“:

make xconfig

o un “make gconfig” si tenemos las GTK 2.0:

make gconfig

La primera vez que vayamos a configurar el kernel, se usará como configuración inicial la de nuestro kernel actual, que si es el de la distribución suele ser un buen punto de partida. La configuración de cada kernel se suele guardar junto al fichero principal del kernel en /boot/config-2.6.XX-YYYY si la instalación anterior lo ha copiado ahí, pero los “make (menu|x|g)?config” lo que hacen es leer la configuración guardada en el interior del kernel en funcionamiento a la que nosotros podemos acceder mediante /proc/config.gz. En la ayuda de General setupKernel .config support leemos:

This option enables the complete Linux kernel ".config" file
contents to be saved in the kernel. It provides documentation
of which kernel options are used in a running kernel or in an
on-disk kernel. This information can be extracted from the kernel
image file with the script scripts/extract-ikconfig and used as
input to rebuild the current kernel or to build another kernel.
It can also be extracted from a running kernel by reading
/proc/config.gz if enabled (below).

Si los scripts de configuración no detectan la configuración del kernel en ejecución, usarán una por defecto, pero siempre podemos copiar la que queramos al fichero /usr/src/linux/.config.

Bueno, en este punto, ya es cosa de cada uno lo que le quiera quitar y poner al kernel. Yo desde luego, tengo la mano muy larga y me lío a quitar absolutamente todo, todo lo que crea que no me va a hacer falta. Prefiero encontrarme con que no puedo hacer algo por falta de una funcionalidad del kernel en concreto y habilitarla y recompilar para así ser consciente de qué estoy habilitando, para qué hace falta, y quién lo usa. La posición cómoda y sencilla es, desde luego, tener tantas cosas habilitadas como sea posible para tener que recompilar las mínimas veces posibles, aunque la primera vez que lo hagamos tardará muchísimo más tiempo. ¿Te interesa más aprender? ¿Te interesa más compilar una vez y olvidarte? ¿Te interesa que tarde poco en compilar? Cada uno que se compile el kernel según sus gustos/necesidades/objetivos.

Lo único que sí que recomendaría es que se le dé un nombre de subversión al kernel para no confundirlo con el estándar de la distribución. Lo podemos hacer en General setupLocal version - append to kernel release:

make menuconfig - local version

Todos mis kernels suelen tener la coletilla -VIC.

Tras configurar el kernel, salimos, guardamos y hacemos un make. En versiones anteriores, hacía falta además hacer un “make modules” para que se compilaran los módulos, pero en versiones recientes del kernel ya se compilan solos al hacer el make.

# make
scripts/kconfig/conf -s arch/x86_64/Kconfig
CHK include/linux/version.h
UPD include/linux/version.h
CHK include/linux/utsrelease.h
UPD include/linux/utsrelease.h
SYMLINK include/asm -> include/asm-x86_64
CC arch/x86_64/kernel/asm-offsets.s
GEN include/asm-x86_64/asm-offsets.h
[...]
CC sound/usb/snd-usb-audio.mod.o
LD [M] sound/usb/snd-usb-audio.ko
CC sound/usb/snd-usb-lib.mod.o
LD [M] sound/usb/snd-usb-lib.ko

Vemos la compilación de los módulos en las líneas señaladas con [M]. Si el kernel no compila bien, es buena idea probar a hacer un “make clean“, que limpia los ficheros objeto existentes y no es tan agresivo como el “make mrproper” que llega a borrar hasta el fichero .config.

Ahora ya tenemos el kernel compilado, así que pasamos a instalarlo con “make install” y “make modules_install“:

# make install
sh /usr/src/linux-2.6.23.9/arch/i386/boot/install.sh 2.6.23.9-VIC arch/x86_64/boot/bzImage System.map "/boot"
In order to use the new kernel image you have just installed, you
will need to reboot the machine. First, however, you will need to
either make a bootable floppy diskette, re-run LILO, or have GRUB
installed.

Checking for ELILO...No

GRUB is installed. To automatically switch to new kernels, point your
default entry in menu.lst to /boot/vmlinuz-2.6.23.9-VIC
# make modules_install
INSTALL arch/x86_64/crypto/aes-x86_64.ko
INSTALL arch/x86_64/crypto/twofish-x86_64.ko
INSTALL arch/x86_64/kernel/cpufreq/powernow-k8.ko
INSTALL arch/x86_64/kernel/cpuid.ko
INSTALL arch/x86_64/kernel/microcode.ko
[...]
INSTALL sound/usb/snd-usb-audio.ko
INSTALL sound/usb/snd-usb-lib.ko
if [ -r System.map -a -x /sbin/depmod ]; then /sbin/depmod -ae -F System.map 2.6.23.9-VIC; fi

El “make modules_install” instalará los módulos en /lib/modules/2.6.23.9-VIC/ borrando cualquier fichero anterior que hubiera en dicho directorio. Es por eso que si teníamos otros módulos además de los estándar del kernel instalados en este directorio (p.e. los del VMWare, kqemu, driver binario de NVidia), tendremos que volver a instalarlos tras el modules_install.

En /boot ahora podemos encontrar el nuevo kernel perfectamente instalado junto con el estándar de la distribución (2.6.22-3-amd64) y cualquier otro que ya tuviéramos (2.6.22.10-VIC):

# ll /boot | egrep -i 'system|config|vmlin|init'
lrwxrwxrwx 1 root root 23 2007-12-09 18:49 System.map -> System.map-2.6.23.9-VIC
-rw-r--r-- 1 root root 1070937 2007-11-04 19:57 System.map-2.6.22-3-amd64
-rw-r--r-- 1 root root 1131081 2007-11-18 21:00 System.map-2.6.22.10-VIC
-rw-r--r-- 1 root root 1121932 2007-12-09 18:49 System.map-2.6.23.9-VIC
lrwxrwxrwx 1 root root 19 2007-12-09 18:49 config -> config-2.6.23.9-VIC
-rw-r--r-- 1 root root 73197 2007-11-04 19:57 config-2.6.22-3-amd64
-rw-r--r-- 1 root root 44991 2007-11-18 21:00 config-2.6.22.10-VIC
-rw-r--r-- 1 root root 44797 2007-12-09 18:49 config-2.6.23.9-VIC
lrwxrwxrwx 1 root root 25 2007-11-30 21:21 initrd.img -> initrd.img-2.6.22-3-amd64
-rw-r--r-- 1 root root 5845083 2007-11-30 21:21 initrd.img-2.6.22-3-amd64
-rw-r--r-- 1 root root 2723176 2007-11-18 21:48 initrd.img-2.6.22.10-VIC
lrwxrwxrwx 1 root root 24 2007-11-01 08:58 initrd.img.vic -> initrd.img-2.6.22.10-VIC
lrwxrwxrwx 1 root root 20 2007-12-09 18:49 vmlinuz -> vmlinuz-2.6.23.9-VIC
-rw-r--r-- 1 root root 1555880 2007-11-04 19:56 vmlinuz-2.6.22-3-amd64
-rw-r--r-- 1 root root 2056648 2007-11-18 21:00 vmlinuz-2.6.22.10-VIC
-rw-r--r-- 1 root root 2017464 2007-12-09 18:49 vmlinuz-2.6.23.9-VIC
lrwxrwxrwx 1 root root 21 2007-11-01 08:57 vmlinuz.vic -> vmlinuz-2.6.22.10-VIC

Por supuesto, a menos que el kernel ya tenga integrados todos los drivers necesarios para arrancar, necesitaremos crear un initrd, tal y como ya vimos en: Hibernación en Linux con TuxOnIce. Notas sobre los initrd y sobre cpio:

# mkinitramfs -o /boot/initrd.img-2.6.23.9-VIC 2.6.23.9-VIC

Si ejecutamos ahora un update-grub:

# update-grub
Searching for GRUB installation directory ... found: /boot/grub
Searching for default file ... found: /boot/grub/default
Testing for an existing GRUB menu.lst file ... found: /boot/grub/menu.lst
Searching for splash image ... none found, skipping ...
Found kernel: /boot/vmlinuz
Found kernel: /boot/vmlinuz-2.6.23.9-VIC
Found kernel: /boot/vmlinuz-2.6.22.10-VIC
Found kernel: /boot/vmlinuz-2.6.22-3-amd64
Updating /boot/grub/menu.lst ... done

nuestro nuevo kernel será añadido entre los AUTOMAGIC KERNELS LIST del /boot/grub/menu.lst:

### BEGIN AUTOMAGIC KERNELS LIST
[...]
title Debian GNU/Linux, kernel 2.6.23.9-VIC
root (hd0,0)
kernel /boot/vmlinuz-2.6.23.9-VIC root=/dev/mapper/nvidia_bdehcbaa3 ro
initrd /boot/initrd.img-2.6.23.9-VIC
savedefault

title Debian GNU/Linux, kernel 2.6.23.9-VIC (single-user mode)
root (hd0,0)
kernel /boot/vmlinuz-2.6.23.9-VIC root=/dev/mapper/nvidia_bdehcbaa3 ro single
initrd /boot/initrd.img-2.6.23.9-VIC
savedefault
[...]
### END DEBIAN AUTOMAGIC KERNELS LIST

Si queremos arrancarlo con unas opciones determinadas, mejor nos hacemos una configuración específica fuera de esta sección para que no sea machacada con los update-grub que se ejecutan cuando el “apt-get dist-upgrade” nos actualiza el kernel estándar. Por supuesto, no hay ningún problema de convivencia de nuestro kernel con el estándar, viniéndonos el estándar de la distribución tremendamente bien para arrancar el sistema cuando el nuestro no nos arranca bien por algún fallo que hayamos cometido al configurarlo.

Yo tengo la costumbre de crear dos enlaces simbólicos con extensión .vic para señalar mi kernel por defecto:

# cd /boot
# ln -s -f initrd.img-2.6.23.9-VIC initrd.img.vic
# ln -s -f vmlinuz-2.6.23.9-VIC vmlinuz.vic
# ll vmlinuz.vic initrd.img.vic
lrwxrwxrwx 1 root root 23 2007-12-09 19:05 /boot/initrd.img.vic -> initrd.img-2.6.23.9-VIC
lrwxrwxrwx 1 root root 20 2007-12-09 19:06 /boot/vmlinuz.vic -> vmlinuz-2.6.23.9-VIC

y así usarlos en el /boot/grub/menu.lst:

title  linux
root (hd0,2)
kernel /boot/vmlinuz.vic root=/dev/mapper/nvidia_bdehcbaa3 resume=swap:/dev/mapper/nvidia_bdehcbaa5 vga=840
initrd /boot/initrd.img.vic

Tras reiniciar con nuestro nuevo kernel, podemos ver la nueva versión en la primera línea del dmesg:

# dmesg
Linux version 2.6.23.9-VIC (root@ordenador) (gcc version 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)) #1 SMP Sun Dec 9 18:45:11 CET 2007

y en la salida del uname:

# uname -a
Linux ordenador 2.6.23.9-VIC #1 SMP Sun Dec 9 18:45:11 CET 2007 x86_64 GNU/Linux

Si necesitamos aplicarle algún parche al kernel, podemos ver cómo lo hicimos en: Solucionando el error “attempt to access beyond end of device” con reglas de udev, hal y/o un parche del kernel o en: Hibernación en Linux con TuxOnIce. Notas sobre los initrd y sobre cpio.

Anexo sobre el VMWare Server 1.0.4 con el kernel 2.6.23

Y finalmente, acabo de comprobar que mientras que los módulos del VMWare Server 1.0.4 compilaban sin problemas con el kernel 2.6.22, con el kernel 2.6.23 no lo hacen dando el siguiente error:

make: Entering directory `/tmp/vmware-config1/vmmon-only'
make -C /lib/modules/2.6.23.9-VIC/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-2.6.23.9'
CC [M] /tmp/vmware-config1/vmmon-only/linux/driver.o
/tmp/vmware-config1/vmmon-only/linux/driver.c: In function 'LinuxDriver_Ioctl':
/tmp/vmware-config1/vmmon-only/linux/driver.c:1659: error: 'struct mm_struct' has no member named 'dumpable'
make[2]: *** [/tmp/vmware-config1/vmmon-only/linux/driver.o] Error 1
make[1]: *** [_module_/tmp/vmware-config1/vmmon-only] Error 2
make[1]: Leaving directory `/usr/src/linux-2.6.23.9'
make: *** [vmmon.ko] Error 2
make: Leaving directory `/tmp/vmware-config1/vmmon-only'
Unable to build the vmmon module.

La solución ya la vimos en Cómo solucionar incompatibilidades entre una versión de VMWare y un kernel más reciente, y pasa por usar el vmware-any-any-releaseXXX de http://platan.vc.cvut.cz/ftp/pub/vmware.



0 comentarios :

Publicar un comentario

Por favor deje su comentario de acuerdo al tema tratado,no se permite polemica,spam,insultos o armar debates fuera de tono.

Related Posts Plugin for WordPress, Blogger...
Mi perfil de Google +