7.4. Manejo de dispositivos y módulos en un sistema LFS

En el Capítulo 6 se instaló el paquete Udev. Antes de entrar en detalles sobre cómo funciona, repasaremos los anteriores métodos de manejo de dispositivos.

Tradicionalmente, los sistemas Linux en general utilizan un método estático de creación de dispositivos, implicando que un gran número de nodos de dispositivo son creados en /dev (literalmente, cientos de nodos) sin tener en cuenta si el dispositivo hardware correspondiente existe en realidad. Esto se hace típicamente mediante un guión MAKEDEV, que contiene una serie de llamadas al programa mknod con los números mayor y menor correspondientes a cada posible dispositivo que pudiera existir en el mundo. Con el uso del método Udev, sólo se crearán los nodos correspondientes a aquellos dispositivos detectados por el núcleo. Debido a que estos nodos de dispositivo se crearán cada vez que se inicie el sistema, se almacenarán en un tmpfs (un sistema de ficheros que existe por completo en memoria y no ocupa espacio en disco). Los nodos de dispositivo no necesitan mucho espacio, por lo que la memoria utilizada es muy poca.

7.4.1. Historia

En Febrero de 2000, un nuevo sistema de ficheros llamado devfs fue incluido en los núcleos 2.3.46 y estuvo disponible en la serie 2.4 de los núcleos estables. Aunque estaba presente en las propias fuentes del núcleo, este método de creación dinámica de dispositivos nunca recibió mucho apoyo por parte del equipo de desarrolladores del núcleo.

El principal problema con el sistema adoptado por devfs era el modo en el que manejaba la detección, creación y denominación de dispositivos. El último punto, la denominación de los nodos, fue quizás el más crítico. Está generalmente aceptado que si los nombres de dispositivos son configurables, entonces las políticas de denominación deberían ser establecidas por un administrador del sistema y no impuestas por un desarrollador en particular. El sistema de ficheros devfs sufre también de extraños comportamientos inherentes a su diseño y que no pueden corregirse sin una revisión sustancial del núcleo. También se ha marcado como descartado debido a la falta de mantenimiento reciente.

Con el desarrollo del árbol inestable 2.5 del núcleo, posteriormente liberado como núcleos estables de la serie 2.6, aparece un nuevo sistema de ficheros virtual llamado sysfs. El trabajo de sysfs es exportar una visión de la configuración hardware del sistema a los procesos de usuario. Con esta representación visible a nivel de usuario, la posibilidad de encontrar un sustituto para devfs a nivel de usuario se hace mucho más real.

7.4.2. Implementación de Udev

Arriba se mencionó brevemente el sistema de ficheros sysfs. Uno podría preguntarse cómo conoce sysfs los dispositivos presentes en el sistema y qué números de dispositivo debe usar. Los crontroladores que se han compilado directamente dentro del núcleo registran sus objetos en sysfs a medida que son detectados por el núcleo. Para los controladores compilados como módulos, esto sucederá cuando se cargue el módulo. Una vez montado el sistema de ficheros sysfs (en /sys), los datos registrados en sysfs por los controladores están disponibles para los procesos de usuario y para que udev cree los nodos de dispositivo.

El guión de inicio S10udev se ocupa de la creación de dichos nodos de dispositivo cuando se inicia Linux. Este guión comienza registrando /sbin/udevsend como manejador de eventos “hotplug”. Los eventos hotplug (explicados más adelante) no deberían generarse durante esta fase, pero se registra udev por si ocurriesen. Entonces, el programa udevstart recorre el sistema de ficheros /sys y crea en /dev los dispositivos que coinciden con las descripciones. Por ejemplo, /sys/class/tty/vcs/dev contiene la cadena “7:0”. Esta cadena la utiliza udevstart para crear /dev/vcs con el número mayor 7 y menor 0. Los nombres y permisos de los nodos creados bajo el directorio /dev se configuran según las reglas especificadas en los ficheros que hay dentro del directorio /etc/udev/rules.d/. Estos están numerados de forma similar a los guiones de arranque LFS. Si udev no puede encontrar una reghla para el dispositivo que está creando, establecerá los permisos por defecto a 660 y el propietario a root:root.

Una vez completado el proceso anterior, estarán disponibles para el usuario todos los dispositivos realmente presentes y cuyos controladores estén compilados dentro del núcleo. Esto nos deja con los dispositivos que tienen controladores modulares.

Anteriormente mencionamos el concepto de un “manejador de eventos hotplug”. Cuando el núcleo detecte la conexión de un nuevo dispositivo, generará un evento de conexión en caliente (hotplug) y mirará en /proc/sys/kernel/hotplug para determinar el programa de nivel de usuario que maneja la conexión de dispositivos. El guión de inicio udev registró udevsend como dicho manejador. Cuando se generan estos eventos hotplug, el núcleo le indica a udev que compruebe en el sistema de ficheros /sys la información relativa a este nuevo dispositivo y que cree para él la entrada en /dev.

Esto nos expone a un problema que existe con udev y que antes existía con devfs. Se conoce comúnmente como el problema de “el huevo y la gallina”. La mayoría de distribuciones Linux manejan la carga de módulos mediante entradas en /etc/modules.conf. Los accesos a un nodo de dispositivo provocan que se cargue el módulo del núcleo correspondiente. Este método no funcionará con udev debido a que el nodo de dispositivo no existe hasta que se cargue el módulo. Para solucionar esto, se añadió al paquete LFS-Bootscripts el guión de inicio S05modules junto con el fichero /etc/sysconfig/modules. Mediante la adición de los nombres de los módulos al fichero modules, estos módulos se cargarán al iniciar el ordenador. Esto permite a udev detectar los dispositivos y crear los nodos corespondientes.

Ten en cuenta que en máquinas lentas o para dispositivos que crean muchos nodos, el proceso de creación puede tadar varios segundos en completarse. Esto significa que algunos nodos de dispositivo no estarán disponibles inmediatamente.

7.4.3. Manejo dinámico de dispositivos

Cuando conectas un dispositivo, como un reproductor MP3 por USB, el núcleo reconoce que el disposiivo se encuentra ahora conectado y genera un evento hotplug. Si el controlador se encuentra cargado (porque fue compilado dentro del núcleo o cargado por el guión de arranque S05modules), se llamará a udev para crear los nodos de dispositivo adecuados según los datos de sysfs disponibles en /sys.

Si el controlador para el dispositivo recién conectado se encuentra disponible como módulo pero no está cargado, el paquete Hotplug cargará el módulo correspondiente y hará que dicho dispositivo esté disponible creando para él el/los nodo(s) de dispositivo.

7.4.4. Problemas con la creación de dispositivos

Hay unos cuantos problemas conocidos cuando se trata la creación automática de nodos de dispositivos:

1) Puede que un controlador del núcleo no exporte sus datos a sysfs.

Esto es muy común con controladores suministrados por el fabricante y ajenos al árbol del núcleo. Udev no será capaz de crear automáticamente los nodos de dispositivo para dichos controladores. Para crear manualmente los dispositivos, utiliza el fichero de configuración /etc/sysconfig/createfiles. Consulta el fichero devices.txt de la documentación del núcleo, o la documentación de dicho controlador, para encontrar los números mayor y menor adecuados.

2) Se necesita un controlador que no pertenece al hardware. Esto es muy común con los módulos de compatibilidad Open Sound System (OSS, Sistema Abierto de Sonido) del proyecto Advanced Linux Sound Architecture (ALSA, Arquitectura Avanzada de Sonido en Linux). Se puede manejar este tipo de dispositivos de dos formas:

  • Añadiendo los nombres de los módulos a /etc/sysconfig/modules

  • Usando una línea “install” en /etc/modprobe.conf. Esto le indica al comando modprobe que “cuando se cargue este módulo, cargue también y al mismo tiempo este otro módulo”. Por ejemplo:

    install snd-pcm modprobe -i snd-pcm ; modprobe \
        snd-pcm-oss ; true

    Esto provocará que el sistema cargue tanto el módulo snd-pcm como el módulo snd-pcm-oss cuando se haga cualquier petición para cargar el módulo snd-pcm.

7.4.5. Lecturas útiles

En los siguientes sitios hay disponible documentación de ayuda adicional: