Um módulo do kernel pode não ser um driver de dispositivo.
"Driver do kernel" não é um termo bem definido, mas vamos tentar.
Este é um módulo do kernel que não conduz nenhum hardware e, portanto, não pode ser considerado razoavelmente um "driver 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)
Após a compilação, você pode usá-lo com:
insmod hello.ko
e imprime hello init
para dmesg
.
No entanto, existem módulos do kernel que não são drivers de dispositivo, mas são realmente úteis, por exemplo, módulos que expõem informações de depuração / desempenho do kernel.
Drivers de dispositivo geralmente também são módulos do kernel.
Um exemplo de algo que é um "driver de dispositivo" é um pouco mais difícil de gerar, pois requer um hardware para dirigir e as descrições de hardware tendem a ser complicadas.
No entanto, usando o QEMU ou outros emuladores, podemos construir modelos de software de hardware real ou simplificado, o que é uma ótima maneira de aprender a conversar com o hardware. Aqui está um exemplo simples de um driver de dispositivo PCI mínimo: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c
Vemos então que, no x86, conversar com o hardware se resume a:
Em geral, essas operações não podem ser realizadas a partir da terra do usuário, conforme explicado em: Qual é a diferença entre o espaço do Usuário e o espaço do Kernel? No entanto, existem algumas exceções: https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space .
O kernel oferece APIs de nível superior para tornar essa interação de hardware mais fácil e mais portátil:
request_irq
lidar com interrupções
ioreadX
mapeamento de memória IO
- interfaces de nível ainda mais alto para protocolos populares como PCI e USB