Un módulo del kernel es un fragmento de código compilado que se puede insertar en el kernel en tiempo de ejecución, como con insmod
o modprobe
.
Un controlador es un fragmento de código que se ejecuta en el kernel para comunicarse con algún dispositivo de hardware. "Conduce" el hardware. Casi todo el hardware de su computadora tiene un controlador asociado.¹ Una gran parte de un núcleo en ejecución es el código del controlador.²
Un controlador puede construirse estáticamente en el archivo del kernel en el disco.³ Un controlador también puede construirse como un módulo del kernel para que pueda cargarse dinámicamente más tarde. (Y luego tal vez descargado.)
La práctica estándar es crear controladores como módulos del kernel siempre que sea posible, en lugar de vincularlos estáticamente al kernel, ya que eso brinda más flexibilidad. Sin embargo, hay buenas razones para no hacerlo:
-
A veces, un controlador determinado es absolutamente necesario para ayudar a que el sistema arranque. Eso no sucede tan a menudo como te imaginas, debido a la función initrd.
-
Los controladores creados estáticamente pueden ser exactamente lo que desea en un sistema que tiene un alcance estático, como un sistema integrado. Es decir, si sabe de antemano exactamente qué controladores se necesitarán siempre y que esto nunca cambiará, tiene una buena razón para no molestarse con los módulos dinámicos del kernel.
-
Si construye su kernel de forma estática y deshabilita la función de carga de módulos dinámicos de Linux, evita la modificación del código del kernel en tiempo de ejecución. Esto proporciona seguridad y estabilidad adicionales a expensas de la flexibilidad.
No todos los módulos del núcleo son controladores. Por ejemplo, una característica relativamente reciente en el kernel de Linux es que puede cargar un programador de procesos diferente. Otro ejemplo es que los tipos de hardware más complejos a menudo tienen múltiples capas genéricas que se ubican entre el controlador de hardware de bajo nivel y el espacio del usuario, como el controlador USB HID, que implementa un elemento particular de la pila USB, independientemente del hardware subyacente.
Aparte:
-
Una excepción a esta declaración general es el chip de la CPU, que no tiene un "controlador" per se . Su computadora también puede contener hardware para el cual no tiene controlador.
-
El resto del código en el kernel de un sistema operativo proporciona servicios genéricos como administración de memoria, IPC, programación, etc. Estos servicios pueden servir principalmente a aplicaciones de usuario, como en los ejemplos vinculados anteriormente, o pueden ser servicios internos utilizados por controladores u otros servicios internos. infraestructura del núcleo.
-
El de
/boot
, cargado en la RAM en el momento del arranque por el cargador de arranque al principio del proceso de arranque.
Para responder a su pregunta específica sobre el lspci
salida, la línea "controlador del núcleo" se refiere a qué controlador está vinculado actualmente a la tarjeta, en este caso el propietario nvidia
conductor. La línea "módulos del núcleo" enumera todos los controladores que se sabe capaz de unirse a esta tarjeta. Aquí, el controlador propietario muestra un nombre diferente, probablemente debido a cómo lspci
encontró el controlador y su nombre de archivo frente al nombre codificado en el propio controlador.
Es posible que un módulo del núcleo no sea un controlador de dispositivo
"Controlador del kernel" no es un término bien definido, pero intentémoslo.
Este es un módulo del kernel que no controla ningún hardware y, por lo tanto, no podría considerarse razonablemente un "controlador de dispositivo":
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int myinit(void)
{
printk(KERN_INFO "hello init\n");
return 0;
}
static void myexit(void)
{
printk(KERN_INFO "hello exit\n");
}
module_init(myinit)
module_exit(myexit)
Después de la compilación, puede usarlo con:
insmod hello.ko
e imprime hello init
a dmesg
.
Sin embargo, hay módulos del núcleo que no son controladores de dispositivos, pero que son realmente útiles, por ejemplo, módulos que exponen información de depuración/rendimiento del núcleo.
Los controladores de dispositivos suelen ser también módulos del núcleo.
Un ejemplo de algo que es un "controlador de dispositivo" es un poco más difícil de generar, ya que requiere un hardware para controlarlo y las descripciones del hardware tienden a ser complicadas.
Sin embargo, usando QEMU u otros emuladores, podemos construir modelos de software de hardware real o simplificado, que es una excelente manera de aprender a hablar con el hardware. Aquí hay un ejemplo simple de un controlador de dispositivo PCI mínimo:https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c
Luego vemos que en x86, hablar con el hardware se reduce a:
in
yout
instrucciones, por ejemplo, https://stackoverflow.com/questions/3215878/what-are-in-out-instructions-in-x86-used-for/33444273#33444273- manejo de interrupciones mediante el registro de controladores con la CPU
En general, esas operaciones no se pueden realizar desde el espacio del usuario, como se explica en:¿Cuál es la diferencia entre el espacio del usuario y el espacio del kernel? Sin embargo, hay algunas excepciones:https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space.
Luego, el kernel ofrece API de nivel superior para hacer que la interacción con el hardware sea más fácil y portátil:
request_irq
para manejar interrupcionesioreadX
y mapeo de memoria IO- interfaces de nivel superior para protocolos populares como PCI y USB