Un modulo kernel potrebbe non essere affatto un driver di dispositivo.
"Driver del kernel" non è un termine ben definito, ma proviamolo.
Questo è un modulo del kernel che non guida alcun hardware e quindi non può essere ragionevolmente considerato un "driver di periferica":
#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)
Dopo la compilazione, puoi usarlo con:
insmod hello.ko
e stampa hello init
su dmesg
.
Esistono, tuttavia, moduli del kernel che non sono driver di dispositivo, ma sono effettivamente utili, ad esempio moduli che espongono le informazioni di debug / prestazioni del kernel.
I driver di dispositivo sono generalmente anche moduli del kernel.
Un esempio di qualcosa che è un "driver di dispositivo" è un po 'più difficile da generare, poiché richiede un hardware da guidare e le descrizioni dell'hardware tendono ad essere complicate.
Utilizzando QEMU o altri emulatori, tuttavia, possiamo costruire modelli software di hardware reale o semplificato, il che è un ottimo modo per imparare a parlare con l'hardware. Ecco un semplice esempio di un driver di dispositivo PCI minimo: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c
Vediamo quindi che in x86, parlare con l'hardware si riduce a:
Queste operazioni non possono in genere essere eseguite da userland, come spiegato in: Qual è la differenza tra spazio utente e spazio kernel? Vi sono tuttavia alcune eccezioni: https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space .
Il kernel offre quindi API di livello superiore per rendere tale interazione hardware più semplice e portatile:
request_irq
gestire gli interrupt
ioreadX
e mappatura della memoria IO
- interfacce di livello ancora più elevato per protocolli popolari come PCI e USB