Moduł jądra może w ogóle nie być sterownikiem urządzenia.
„Sterownik jądra” nie jest dobrze zdefiniowanym terminem, ale dajmy mu szansę.
Jest to moduł jądra, który nie napędza żadnego sprzętu, a zatem nie może być uznany za „sterownik urządzenia”:
#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)
Po kompilacji możesz go używać z:
insmod hello.ko
i drukuje hello init
do dmesg
.
Istnieją jednak moduły jądra, które nie są sterownikami urządzeń, ale są faktycznie przydatne, np. Moduły, które ujawniają informacje o debugowaniu / wydajności jądra.
Sterowniki urządzeń są zwykle również modułami jądra.
Przykład czegoś, co jest „sterownikiem urządzenia”, jest nieco trudniejszy do wygenerowania, ponieważ wymaga sprzętu do napędu, a opisy sprzętu bywają skomplikowane.
Za pomocą QEMU lub innych emulatorów możemy jednak konstruować modele oprogramowania rzeczywistego lub uproszczonego sprzętu, co jest doskonałym sposobem na nauczenie się, jak rozmawiać ze sprzętem. Oto prosty przykład minimalnego sterownika urządzenia PCI: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c
Następnie widzimy, że w x86 rozmowa ze sprzętem sprowadza się do:
Zasadniczo tych operacji nie można wykonać z przestrzeni użytkownika, jak wyjaśniono na stronie: Jaka jest różnica między przestrzenią użytkownika a przestrzenią jądra? Istnieją jednak pewne wyjątki: https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space .
Jądro następnie oferuje interfejsy API wyższego poziomu, aby taka interakcja sprzętowa była łatwiejsza i bardziej przenośna:
request_irq
do obsługi przerwań
ioreadX
i mapowanie pamięci IO
- jeszcze wyższy poziom interfejsów popularnych protokołów, takich jak PCI i USB