2. Kernel y módulos

Indicadores de Logros:

2.1. Lectura: Kernel y módulos

En un sistema Linux la interacción final con dispositivos la realizan los controladores o el kernel. Dicho de otra forma, un dispositivo sólo podrá ser usado si el kernel lo soporta o si existe un controlador capaz de controlarlo y si se configura apropiadamente para hacerlo. Por esto, los dispositivos que se produzcan hoy, no pueden ser operados con controladores ya existentes (a menos que los dispositivos hayan sido diseñados para ser operados con estos ---caso que para algunos dispositivos como tarjetas de sonido, tarjetas de video o modems es poco común), por esto mismo, eventualmente, si actualiza el hardware de su computador o si desea usar un cierto servicio del kernel, también deberá actualizar algún módulo o eventualmente el kernel completo. Aunque algunos controladores autodetectan la configuración del dispositivo, esto no siempre ocurre y en algunos casos tendrá que probar (cacharrear), hasta hacer funcionar el módulo que maneja el dispositivo (en estas pruebas la documentación del dispositivo, la del módulo y estas guías, esperamos le sean de utilidad ---si desea experimentar rapidamente emplee modconf).

Las fuentes en C de cada versión del kernel cuentan con controladores para diversos dispositivos. Cuando se compila una versión, algunos de esos controladores pueden unirse con el kernel mismo (estáticamente), otros pueden dejarse como módulos para cargarse/descargarse cuando la parte estática del kernel este operando, otros pueden ser excluidos del proceso de compilación (y por lo tanto no podrán ser usados ni cuando el kernel esté operando).

2.1.1. Módulos

En este contexto, módulo se refiere a un controlador de un dispositivos o servicio que puede cargarse o descargarse cuando el usuario o algún dispositivo lo solicita (i.e dinámicamente). Los módulos que se distribuyen con en el kernel están ubicados en el directorio /lib/modules/version, donde version es la versión de su kernel [112], con la extensión .o [113] organizados en directorios que indican el tipo de dispositivo o el propósito, por ejemplo fs - sistema de archivos, net - protocolos y hardware para redes.

Para lograr configurar un dispositivo controlado por un módulo, puede emplear las herramientas del paquete modutils o modconf para:

  1. Asegurar que no haya conflictos entre el dispositivo con otros y eventualmente conocer la configuración que usa (algunos controladores autodetectan la configuración del dispositivo, pero no todos).

  2. Encontrar un módulo que pueda manejar el dispositivo.

  3. Eventualmente pasar opciones al módulo de acuerdo a la configuración del dispositivo (e.g IRQ o dirección base).

En Debian las herraminetas del paquete modutils se configuran en los achivos del directorio /etc/modutils (con la información de esos archivos y de /etc/modules se genera el archivo de configuración de módulos /etc/modules.conf [114]). Los programas que ese paquete incluye son:

lsmod

Lista los módulos cargados, de cada uno presenta nombre, tamaño, cuenta de usos y lista de módulos que lo usan (es equivalente a cat /proc/modules).

rmmod módulos

Descarga uno o más módulos cargados, mientras estos no estén siendo usados. Con la opción -r intenta descargar recursivamente módulos de los cuales el módulo especificado dependa. El comando rmmod -a descarga todos los módulos que no estén siendo usados.

insmod módulo [opciones]

Trata de cargar el módulo especificado. Pueden pasarse opciones específicas para el módulo, a continuación del nombre con la sintaxis símbolo=valor (los símbolos posibles dependen del módulo, pueden verse algunos en estas guías o en /usr/share/modconf/descr.gz --- que es la ayuda presentada por modconf --- o en último caso en las fuentes del módulo en los macros MODULE_PARAM y MODULE_PARAM_DESCR). Puede indicarse una ruta no estándar para buscar módulos estableciéndola en la variable MODPATH o en /etc/modules.conf. Dado que los módulos se enlazan directamente con el kernel, deben ser compilados para una versión precisa, con la opción -f puede evitarse el chequeo de versiones.

depmod

Como un módulo puede requerir otros, hay dependencias que deben respetarse al cargar y descargar módulos. depmod permite calcular tales dependencias entre varios módulos o entre todos los disponibles con la opción -a [115]. Por defecto depmod -a escribe las dependencias en el archivo /lib/modules/version/modules.emp Cada línea de ese archivo tiene el nombre de un módulo seguido del caracter ':' y los módulos de los cuales depende, separados por espacios.

modprobe módulo opciones

Emplea la información de dependencias generada por depmod e información de /etc/modules.conf para cargar el módulo especificado, cargando antes todos los módulos de los cuales dependa. Para especificar el módulo basta escribir el nombre (sin la ruta, ni la extensión .o) o uno de los alias definidos en /etc/modutils/alias (o en otro archivo del directorio /etc/modutils). Si hay líneas pre-install o post-install en /etc/modules.conf, modprobe puede ejecutar un comando antes y/o después de cargar el módulo. Como opciones para cargar el módulo usa prioritariamente las dadas en la línea de comandos y después las especificadas en líneas de la forma options módulo opciones en el archivo /etc/modules.conf [116]

Puede emplear estos programas para configurar sus módulos y puede hacer permanentes los cambios, agregando el módulo y las opciones en el archivo /etc/modules [117].

Para hacer más fácil la configuración de módulos, Debian ofrece las siguientes herramientas:

modconf

Para listar, cargar y descargar módulos con menús. Este programa muestra los módulos disponbiles en categorías y con ayudas sobre su uso y permite cargarlos o descargarlos del kernel, actualizando automáticamente los archivos /etc/modules y /etc/modules.conf (cambiando los archivos apropiados de /etc/modutils) para que los módulos configurados sean cargados automáticamente en el siguiente arranque. La información sobre los módulos disponibles la obtiene del directorio /lib/modules, los módulos cargados y sus parámetros los lee de /etc/modutils y /etc/modules.conf y la ayuda y la información interna de los archivos en /usr/share/modules.conf ---modconf es un script para el intérprete de comandos.

update-modules

Actualiza el archivo /etc/modules.conf a partir de la información de los archivos del directorio /etc/modutils --- en Debian no se edita directamente /etc/modules.conf.

Es posible que el kernel del que disponga no cuente con módulos que soporten ciertos dispositivos, en tal caso se puede:

  1. buscar en Internet un módulo precompilado para la versión del kernel que tiene,

  2. buscar fuentes de un módulo o

  3. buscar una versión del kernel que incluya soporte para el dispositivo.

En el último caso las instrucciones de la siguiente sección le serán de utilidad.

2.1.2. Configuración del kernel

Además de cargar y descargar módulos, algunas características del kernel pueden ser modificadas mientras está en funcionamiento el sistema, bien escribiendo en algunos archivos del directorio /proc, o con el programa sysctl. Este programa con la opción -a presenta todas las variables modificables y su valor, entre otras encuentra variables que mantienen datos autodetectados en dispositivos (en particular del CDROM), datos de la interacción entre el kernel y el sistema de archivos (ver Sistema de archivos ext2), datos sobre los protocolos y dispositivos de redes, y detalles del kernel.

Para cambiar un valor se emplea:

/sbin/sysctl -w kernel.hostname=comp
      

con un nombre de variable en lugar de kernel.hostname y un valor adecuado en lugar de comp. Pueden hacerse cambios que se vuelven a tomar cada vez que el sistema inicia en el archivo /etc/sysctl.conf.

En cuanto a los módulos, las imagenes precompiladas del kernel producidas por Debian incluyen estáticamente varios controladores comunes y prácticamente los demás controladores los incluye como módulos. Por esto, si la versión del kernel que tiene soporta sus dispositivos y los servicios que desea, casi con seguridad usted NO necesita recompilar el kernel (puede confirmar si la imagen que tiene, soporta el controlador como módulo revisando en el directorio de módulos, o puede comprobar si éste se incluye estáticamente, efectuando el segundo paso para una instalación que se explica más adelante, usando como archivo de configuración el de la imagen de su kernel).

Eventualmente, si su dispositivo no es detectado automáticamente o el módulo apropiado no es cargado automáticamente [118], tendrá que pasar los paramétros apropiados de una de las dos siguientes formas:

Controlado estático

Pase los parámetros apropiados desde el cargador de arranque o configurelos de forma permanente con su cargardor de arranque (ver Parámetros desde el cargador de arranque).

Módulo (dinámico)

Pase los paramétros de configuración a insmod/modprobe o configurelos de forma permanente en /etc/modules, o en un archivo de /etc/modutils (vea la sección anterior sobre módulos).

Eventualmente puede encontrar y usar algún programa que le ayude a determinar los parámetros apropiados y/o a realizar las configuraciones (algunos se mencionan en las secciones de este capítulo), o tendrá que consultar los manuales del dispositivo o incluso probar varias opciones hasta determinarlos.

Si tras consultar esta documentación o la del kernel o cualquier otra más actualizada, determina que una versión del kernel diferente a la que tiene, soporta cierto dispositivo o servicio que requiere, el método más sencillo que puede intentar es instalar una imagén precompilada disponible en algún depósito de paquetes de Debian (el nombre es de la forma kernel-image-version). Como parte del archivo oficial de Debian encontrará imagenes recientes de las series 2.2.x y 2.0.x (por defecto Debian 2.2r5 emplea el kernel 2.2.19).

Fuera del depósito oficial encontrará paquetes para Debian 2.2 de imágenes de la versión 2.4.18 para diversos procesadores e instrucciones en: http://www.fs.tum.de/~bunk/kernel-24.html La instalación es bastante directa y automática (sólo debe tener en cuenta agregar una línea a /etc/lilo.conf para usar initrd).

En caso de requerir un kernel con una configuración muy especial (por ejemplo, que incluya estáticamente ciertos módulos o que excluya de la compilación módulos para hacer un kernel pequeño) o si requiere una versión para la que que no haya imagenes precompiladas de Debian, recomendamos instalar primero una versión precompilada con una versión cercana a la que desea instalar, para tomar la configuración de esta y modificarla antes de compilar la nueva versión. Además recomendamos esto porque las imagenes precompiladas actualizan otros programas indispensables para las nuevas versiones del kernel ---en especial si cambia de la serie 2.2 a la serie 2.4 se deben actualizar : gcc 2.91.66, make 3.77, binutils 2.9.1.0.25, util-linux 2.10o, modutils 2.4.0, e2fsprogs 1.19, pcmcia-cs 3.1.21, PPP 2.4.0.

Para obtener las fuentes, puede recurrir a paquetes Debian para algunas versiones de las fuentes en depósitos oficiales (paquetes con nombres de la forma kernel-sources-version) y las fuentes de cualquier versión en el sitio de desarrollo del kernel (http://www.kernel.org). Cuando obtenga fuentes del kernel de Linux, tenga en cuenta que el segundo número de la versión sea par ---si es impar se trata de una versión para desarrolladores pero NO para usuarios finales.

En esta sección presentamos un breve resumen de los pasos requeridos en una compilación de kernels versiones 2.2.x y 2.4.x, suponiendo que ya ha actualizado todas los programas que estas versiones requieren.

  1. Limpieza Para limpiar posibles compilaciones anteriores emplee:

    make mrproper
    make clean
    

  2. Preparación de la versión extra La versión de un kernel (que puede examinar con uname -r) se compone de 3 números separados por el caracter '.' eventualmente seguidos de una cadena (versión extra). Usted puede establecer esta cadena arbitrariamente y especificarla en el archivo Makefile de las fuentes (variable EXTRAVERSION), por ejemplo:

    EXTRAVERSION= -tobias
    

    Cuando compile, instale y le funcione un nuevo kernel, esa versión será la reportada por uname -r, los módulos que instale por defecto quedarán en /lib/modules/version y serán usados por modutils (ver Kernel y módulos).

    Si escoge una versión extra que coincida con una ya existente, los módulos anteriores serán remplazados durante la instalación. Recomendamos emplear una versión extra diferente a las que pueda haber, mantener el kernel original junto con sus módulos en disco y agregar una etiqueta y los datos requeridos por el cargador de arranque) ---mientras se aprende, es muy normal producir kernels con configuraciones erradas que no podrán arrancar.

  3. Configuración En general el paso más difícil es la configuración de las características que desea del kernel (dada la gran cantidad de preguntas y de términos técnicos, que esperamos estén explicados a lo largo de este capítulo). Para iniciar una configuración completa puede emplear make menuconfig que presentará menús y ayuda, tenga en cuenta que algunas características puede incluirlas estáticamente en el kernel y otras como módulos (las características estáticas aumentan el tamaño). Alternativamente puede emplear make xconfig que presenta una interfaz gráfica o make config que presenta una serie de preguntas. El resultado de cualquier de estos métodos es un archivo .config con las variables de configuración y sus valores.

    Otra posibilidad es que emplee la configuración de un kernel ya instalado y la modifique para acomodarla a sus necesidades. En Debian los archivos de configuración del kernel [119] están en el directorio /boot con nombres de la forma config-version_kernel. Copie uno de estos que corresponda a una versión cercana al que desea compilar, al directorio con las fuentes con el nombre .config después puede modificar la configuración de cualquiera de las siguientes formas: (1) ejecutando make menuconfig que leerá el archivo .config por defecto, (2) ejecutando make xconfig y eligiendo cargar ese archivo o (3) editando .config con un editor de texto y ejecutando después make oldconfig.

  4. Compilación Primero se calculan interdepencias entre archivos fuente de acuerdo a la configuación con make dep, después se compila una imagen del kernel con make bzImage y finalmente se compilan módulos con make modules.

  5. Instalación Es necesario instalar la imagen del kernel, los archivos auxiliares y módulos, configurar el cargador de arranque y eventualmente si está compilando un kernel con initrd (los kernels 2.4 precompildos de Debian por defecto lo usan) debe crear la imagen apropiada. Antes de instalar módulos. En este punto es recomendable que saque una copia de respaldo del directorio de módulos (en caso de que este remplazandolos por la versión extra que escogió). Para instalar emplee make modules_install que copiará todos los módulos y las dependencias entre ellos al directorio /lib/modules/version_kernel. A continuación se presenta un ejemplo que debe adaptar a la versión de su kernel:

    cd /usr/src/kernel-source-2.2.21
    make modules_install
    cp arch/i386/boot/bzImage /boot/vmlinuz-2.2.21-tobias
    ln -s /boot/vmlinuz-2.2.21-tobias /vmlinuz-2.2.21-tobias
    cp System.map /boot/System.map-2.2.21-tobias
    cp .config /boot/config-2.2.21-tobias
    

    Después deberá editar la configuración de su cargador de arranque para que emplee la nueva imagen del kernel, por ejemplo puede agregarse una sección como:

    image=/vmlinuz-2.2.21-tobias
    	root=/dev/hda2
    	label=Potato-tobias
    	read-only
    	append="apm=on"
    

    Cambiando el dispositivo root por el apropiado, la etiqueta y de no requerirse soporte para APM quitando la última línea (ver BIOS y otras características)

    Si está compilando un kernel con initrd [120] (por ejemplo los kernel 2.4 para Debian lo emplean por defecto), debe agregar a la misma sección en /etc/lilo.conf:

    initrd=/initrd.img
    

    Después debe ejecutar /sbin/lilo para poner un nuevo cargador de arranque en el MBR o en el sector de arranque donde esté configurado.

    [Important]Importante

    Después de compilar un kernel, ejecute /sbin/lilo aún si no modifica /etc/lilo.conf

2.2. Lecturas recomendadas: Kernel y módulos

2.3. Ejercicios: Kernel y módulos

2.3.1.

¿Qué versión del kernel Linux tiene instalado su sistema? Ayuda: emplee el programa kernelversion

2.3.2.

Revise los módulos que están cargados en su sistema, y trate de determinar que dispositivo controla o qué servicio presta cada uno.

2.3.3.

Examine el archivo de configuración de X-Window, si desea experimentar con este, saque una copia y modifíquelo directamente o por medio del programa XF86Setup (si no tiene disponible XF86Setup puede intentar con xf86config).

2.3.4.

Al cargar un módulo, insmod revisa que los símbolos del kernel que el módulo espera puedan ser resueltos. ¿Qué son estos símbolos? Describa también como buscó su respuesta.



[112] Versión tal como la reporta uname -r

[113] Esta extensión es típica de código objeto que es código generado por un compilador a partir de un archivo fuente (en el caso de Linux el compilador es gcc). Puede "unirse" estáticamente con más código objeto empleando un encadenador (en el caso de Linux el encadenador es ld) o dinámicamente usando /lib/ld.so (ver Administración de programas) o en el caso de módulos con insmod.

[114] El archivo de configuración de modutils puede variarse especificando uno diferente en la variable MODULECONF

[115] La especificación de las rutas para buscar módulos puede hacerse con MODPATH o en /etc/modules.conf en las líneas de la forma path[tipo]

[116] El archivo /etc/modules.conf puede tener comentarios en líneas iniciadas con el caracter '#', puede tener líneas para: modificar las dependencias entre módulos (below, above, probe, probeall, depfile); para manejar las rutas donde buscar módulos (path, keep); para ejecutar comandos antes, en vez o después de instalar o descargar los módulos (pre-install, install, post-install, pre-remove, remove, post-remove); para especificar opciones por defecto para algunos módulos o insmod (options, insmod_opt); para crear alias o para definir variables o tener en cuenta sólo ciertas partes del archivo (alias, define, if, else, elseif, endif).

[117] Durante el arranque las dependencias entre módulos son generadas automáticamente y los módulos especificados (junto con sus opciones) en el archivo /etc/modules son cargados.

[118] kmod es el programa que se encarga de cargar módulos automáticamente por demanda i.e. sin intervención del usuario

[119] Los archivos de configuración del kernel son dejados en /boot por los paquetes kernel-image-version.

[120] Es una imagen de una partición raíz mínima que reside en memoria RAM, una imagen initrd suele tener controladores y configuraciones que el kernel debe configurar/realizar antes de emplear el dispositivo raiz real.