Ventajas y desventajas de usar el DKMS

publicado en: drivers, tutoriales | 0

La instalación automática de módulos del núcleo de Linux con el marco DKMS es una forma conveniente de distribuir los controladores que se mantienen fuera del núcleo oficial. Sin embargo, aunque DKMS está incluido en muchas distribuciones populares de Linux y es compatible con la mayoría de los módulos del núcleo, no siempre puede garantizar la correcta instalación de un módulo de terceros.

En este artículo, discutimos los pros y los contras de usar DKMS y explicamos en qué casos no es la mejor solución para la instalación de controladores de Linux. Este artículo será útil para los desarrolladores de controladores que están debatiendo si usar DKMS para distribuir su software.

¿Qué es el DKMS?

¿Qué es el DKMS? Dynamic Kernel Module Support (DKMS) es un marco de trabajo desarrollado por Dell para distribuir automáticamente las actualizaciones de los módulos del núcleo a sus clientes. Simplifica tanto el desarrollo de controladores como la administración del sistema, aumentando la estabilidad general del sistema.

Este marco de trabajo permite a los desarrolladores proporcionar a los usuarios controladores que no están incluidos en el lanzamiento oficial del kernel. DKMS también aumenta significativamente la calidad del código fuente de los módulos, ya que los desarrolladores pueden probar sus drivers simultáneamente en numerosas máquinas.

El DKMS también tiene ventajas para los administradores de sistemas, ya que instala automáticamente las actualizaciones de los controladores de los dispositivos en la versión existente del kernel sin introducir ningún cambio en el mismo. Así que los administradores de sistemas ya no tienen que esperar a que se publique una nueva versión del kernel.

Tenga en cuenta que el DKMS no es la única solución para instalar módulos del núcleo. También hay alternativas de DKMS como:

  • AKMOD, una solución de Fedora que se basa en herramientas como la Colección de Compiladores GNU y auto-make
  • asistente de módulos (a menudo abreviado como m-a), una herramienta para compilar manualmente los módulos del núcleo

DKMS y AKMOD son similares, ya que ambos reconstruyen módulos para la instalación de un nuevo kernel, mientras que m-a requiere ejecución manual y puede construir módulos sólo para un kernel actualmente en funcionamiento. Pero esto puede ser un inconveniente, por ejemplo cuando se instala un controlador de gráficos.

Comprendiendo el ciclo de vida del DKMS

Veamos más de cerca cómo funciona el DKMS. El DKMS duplica el árbol de módulos fuera del árbol del núcleo. Este árbol de módulos incluye el código fuente del módulo y sus binarios compilados. Cuando un nuevo kernel de Linux o una nueva versión del controlador es liberada, DKMS usa un enfoque estandarizado para recolectar y construir su código fuente.

Específicamente, DKMS es una herramienta universal que puede construir código de controlador en archivos binarios de módulos compilados cargables, y luego instalar y desinstalar esos módulos en cualquier núcleo de Linux.

Además, el marco proporciona características especiales para la gestión y el mantenimiento de los módulos en múltiples sistemas, mostrando qué versión del módulo está instalada en qué versión del núcleo.

Cuando se considera si se usa el DKMS, es necesario entender el ciclo de vida de su módulo. Aquí está el flujo de DKMS y sus principales comandos para ejecutar y administrar un módulo del núcleo.

Como puedes ver, hay un conjunto especial de comandos para realizar las principales acciones con los controladores de Linux.

Puede ver el estado actual de los módulos ejecutándose:

                estado del dkms

Este comando muestra el nombre, la versión y el estado de cada módulo del núcleo. Usando este comando, puede entender rápidamente si un controlador de dispositivo ha sido actualizado.

Para añadir un módulo y su versión al árbol de DKMS existente, ejecute lo siguiente:

                dkms añadir [-m NOMBRE_MÓDULO] [-v VERSIÓN] [/camino/al/módulo-src/]

Si se omiten las opciones -m o -v, DKMS buscará /usr/src/módulo-módulo-versión en las fuentes así como en el archivo dkms.conf , o copiará el archivo pasado /path/to/module-src/ a /usr/src/módulo-módulo-versión .

Después de que el módulo se coloca en el árbol, puedes construir el módulo usando el comando de construcción:

                dkms build -m MÓDULO -v VERSIÓN -k $(uname -r)

Este comando permite a los desarrolladores y administradores del sistema compilar un módulo previamente agregado para el kernel actual. También permite a los desarrolladores comprobar si hay errores en un controlador durante el desarrollo. Después de esto, su módulo será compilado pero no instalado.

Si quieres copiar los módulos compilados al árbol del núcleo, usa el comando de instalación:

                dkms instalar -m MÓDULO -v VERSIÓN -k $(uname -r)

Si hay dos módulos con el mismo nombre, el módulo previamente instalado será respaldado en el directorio /var/dkms/MODULE/original-module . Se guardará como un módulo original para que pueda ser restaurado si se desinstala el módulo más reciente.

Hay dos comandos para borrar un módulo del árbol DKMS: desinstalar y eliminar .

El comando de desinstalación eliminará el módulo instalado y, si es posible, lo reemplazará con una copia de seguridad:

                dkms desinstalar -m MÓDULO -v VERSIÓN -k $(uname -r)

Para quitar el módulo del árbol del kernel para la versión y arquitectura del kernel pasado -k, ejecutar:

                dkms remover -m MÓDULO -v VERSIÓN -k $(uname -r)

Si quieres quitar un módulo de todos los kernels instalados, añade -all:

                dkms quitar -m MÓDULO -v VERSIÓN -todos

La diferencia entre los comandos remove y uninstall es que uninstall sólo borra un módulo del árbol del núcleo, dejando el módulo en el estado built , mientras que remove también comprueba si existen otras instancias del módulo para otros núcleos y, si no hay ninguna, limpia el árbol DKMS. Después de que el árbol se limpia, el usuario de Linux debe añadir el módulo de nuevo para usarlo con el SGDK.

Otros comandos dignos de mención son el match y el auto-instalador. La orden match es útil cuando se necesita usar un módulo para varios núcleos. En este caso, match utiliza la configuración del módulo instalado en un núcleo y la aplica a otro.

El autoinstalador comprueba si el archivo de configuración contiene el parámetro AUTOINSTALL y, si es así, DKMS reconstruirá e instalará el módulo para este kernel al arrancar en un nuevo kernel.

Para usar el DKMS, debe proporcionar un archivo dkms.conf como este:

                PACKAGE_NAME="MY_MODULE "PACKAGE_VERSION="1.0 "MAKE="make --uname_r=$kernelver "CLEAN="make clean "BUILT_MODULE_NAME="$PACKAGE_NAME "DEST_MODULE_LOCATION="/kernel/drivers/misc "REMAKE_INITRD="yes "AUTOINSTALL="yes

El uso de DKMS depende de la forma en que se proporciona un controlador de Linux a sus usuarios. A continuación, explicaremos por qué.

Principales formas de distribución de controladores de Linux

Los desarrolladores de controladores de Linux pueden distribuir su software de las siguientes formas:

  • Como un módulo de kernel precompilado En este caso, los usuarios de Linux no tienen que preocuparse por los requisitos para construir el controlador. Los módulos precompilados se lanzan con el núcleo de Linux y requieren soporte para diferentes sabores de Linux y diferentes opciones de configuración. Sin embargo, puede pasar algún tiempo entre el lanzamiento de un nuevo núcleo y el lanzamiento de la versión necesaria de un módulo.
  • Como código fuente de módulo completo Con el código fuente de módulo completo, un usuario puede construir un controlador por su cuenta. Pero este método se basa en un compilador instalado, herramientas de construcción adicionales, y los archivos de cabecera del kernel apropiados.
  • Como un módulo del núcleo con partes binarias de código cerrado y código fuente para una capa de interfaz del núcleo
    Este tipo de módulo del núcleo se utiliza a menudo como solución alternativa para la infracción de licencias o distribuciones como Free/Net BSD (Berkeley Software Distribution) y algunas distribuciones de Linux en las que se acepta un firmware binario combinado junto con partes de interfaz de código abierto.

DKMS espera que los módulos del núcleo se suministren con código de código abierto, pero a veces los controladores vienen con partes binarias de código cerrado (como los controladores de vídeo de NVIDIA). En este caso, la parte principal del controlador incluye un objeto vinculado binario de código cerrado, también llamado blob binario, y el código fuente de la capa de interfaz del núcleo. La interfaz del kernel, compilada como un módulo general, debe estar enlazada con las partes de código cerrado y debe ser compilada específicamente para cada kernel.

La construcción de módulos a partir del código fuente suele requerir un paquete de cabeceras de núcleo , un compilador (como la colección de compiladores GNU) y un enlazador (normalmente /usr/bin/ld del paquete binutils ). Estos componentes son necesarios en caso de que se hagan cambios en la parte de código cerrado o sólo en el código fuente de un módulo. En caso de que se haga cualquier cambio en la interfaz binaria de la aplicación del núcleo (ABI), como cambios en las firmas de las funciones, en el número de parámetros o en sus tipos, se requiere la interfaz correcta del núcleo para soportar el código de la interfaz vinculado con la parte blob.

Beneficios y limitaciones del DKMS

Aunque DKMS es sin duda una herramienta útil para la distribución de controladores del núcleo de Linux, tiene limitaciones que pueden hacer que los desarrolladores de controladores se alejen de ella. Así que veamos más de cerca los pros y los contras de DKMS.

Ventajas de utilizar el DKMS:

  • Es un marco conveniente para construir, instalar y eliminar varios módulos del núcleo de Linux.
  • Asegura que un controlador de Linux será actualizado e instalado correctamente en el lugar correcto.
  • Permite gestionar los módulos instalados y comprobar su estado.
  • Le permite añadir un paso personalizado, como la adición de una firma digital de conductor del cliente a través de POST_BUILD y POST_INSTALL. Esto garantiza la seguridad de la instalación del módulo.
  • Soporta la instalación de los paquetes deb y rpm fuera de la caja.
  • Está disponible para muchas distribuciones de Linux.
  • Los usuarios de Linux pueden actualizar sus controladores inmediatamente después de ser reparados. Por lo tanto, no necesitan esperar a que el proveedor les dé una nueva versión del núcleo.
  • Con este marco de trabajo, es difícil olvidarse de instalar el módulo para un núcleo recién instalado porque todos los procesos están automatizados.

Contras de usar DKMS:

  • Se requiere una manipulación adicional para los módulos residentes.
  • El código fuente de los módulos tipo NVIDIA con partes blob no son convenientes para entregar con DKMS, ya que requieren código fuente para la interfaz del kernel compilado para cada versión del kernel.
  • Existe el riesgo de que un módulo no sea construido por DKMS si sus nombres de función han cambiado o si hay cambios en la forma en que el núcleo interactúa con sus componentes.
  • DKMS no garantiza una instalación adecuada en caso de cambios en la interfaz binaria de la aplicación del kernel, ya que la interfaz del kernel y el soporte de la fuente del módulo siguen siendo necesarios.

Distribución de conductores sin DKMS

En uno de nuestros proyectos de desarrollo de controladores para Linux, se nos encargó crear un controlador que estuviera protegido contra la descarga de módulos y los intentos de evitar su carga. Nuestro cliente quería estar seguro de la persistencia del módulo y la secuencia de arranque.

Para lograr este objetivo, decidimos distribuir el controlador con módulos precompilados. Como nuestro driver tenía partes binarias de código cerrado, el uso de DKMS no habría garantizado una instalación adecuada.

Sin embargo, el primer problema que enfrentamos fue una amplia gama de versiones del núcleo de Linux y distribuciones soportadas. Así que tuvimos que elegir a cuál añadir nuestro controlador.

Además, nos encontramos con algunos problemas al implementar nuestro propio sistema de construcción e instalación de módulos:

  • Los usuarios de Linux pueden utilizar diferentes administradores de paquetes, y los nombres de las herramientas de construcción común y los paquetes de encabezamiento del núcleo pueden variar en las distintas distribuciones. Así que existe el riesgo de que nuestro controlador no se construya correctamente.
  • Algunas versiones del núcleo no tienen paquetes disponibles para las cabeceras de los núcleos (por ejemplo, en Fedora), ya que fueron sacados del acceso público.
  • Algunos núcleos de Linux no soportan el algoritmo de firma digital PKCS7, así que tuvimos que usar el mecanismo de firma por defecto en su lugar.
  • Hay un enfoque ambiguo y dependiente de la distribución para obtener una lista de kernels instalados, que confirma la presencia del paquete de cabecera del kernel.
  • Tuvimos problemas con la construcción de módulos en algunas distribuciones/configuraciones específicas. Estos problemas también pueden aparecer en el caso de una construcción automatizada con DKMS u otras herramientas similares.

A continuación, proporcionamos algunos consejos sobre cómo los desarrolladores pueden verificar la instalación de su módulo de Linux en el núcleo sin usar DKMS.

Al implementar un instalador personalizado, el desarrollador de un controlador tiene que elegir cuándo y cómo debe comenzar su módulo, cómo detectar los módulos ya instalados y cómo verificar si los módulos están firmados correctamente.

Estas decisiones deben tomarse incluso si decides usar el modprobe para añadir o quitar tu módulo del kernel de Linux.

Si está considerando usar insmod para insertar su módulo en el kernel, debe tener cuidado de protegerse contra las listas negras. Sin embargo, en este caso, necesitarás implementar el módulo de sistema init desde cero.

En los casos de carga ansiosa o de un módulo residente, los desarrolladores de controladores pueden elegir un guión de nivel de ejecución en lugar de los guiones de inicio automático definidos por el usuario, que suelen utilizarse para el software. Con toda la variedad de sistemas de arranque inicial de Linux (scripts INIT Sys-V, upstart, systemd y otros), la mejor opción es implementar un script personalizado init.d y confiar en las utilidades instaladas (como update-rc.d o chkconfing ) para manejar los enlaces por nivel de ejecución. Runlevel es el concepto para los sistemas operativos con inicialización de estilo Sys-V que describe qué procesos, demonios y controladores deben cargarse o iniciarse para cada modo.

Sin embargo, no hay ninguna norma que defina la ubicación del enlace, la estructura o incluso la lista completa de tales enlaces. Además, las utilidades mencionadas anteriormente tienen diferentes versiones de paquetes en las distribuciones con diferentes funcionalidades. Por ejemplo, una versión anterior de update-rc.d en la Casa de la Moneda 17 permite especificar la prioridad de arranque, pero la misma utilidad en la Casa de la Moneda 18 no tiene esta opción, basándose únicamente en las dependencias de carga de los módulos.

Conclusión

Gracias al continuo desarrollo de la comunidad Linux, aparecen grandes herramientas como DKMS. Con DKMS, los usuarios de Linux pueden construir y gestionar automáticamente los módulos del núcleo sin necesidad de esperar a la entrega de un nuevo paquete de controladores. Además, los desarrolladores de controladores pueden verificar la instalación de sus módulos en la etapa de desarrollo. También hay una amplia gama de herramientas útiles para los desarrolladores de controladores de Linux, por lo que seguiremos compartiendo nuestra experiencia en este tema. El desarrollo de controladores Linux requiere un enfoque integral, y nuestro equipo de desarrolladores de controladores está siempre a su disposición.

Servicios conexos

Desarrollo del núcleo y del controlador

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *