Ein Kernelmodul ist möglicherweise überhaupt kein Gerätetreiber.
"Kerneltreiber" ist kein genau definierter Begriff, aber lassen Sie es uns versuchen.
Dies ist ein Kernelmodul, das keine Hardware antreibt und daher nicht als "Gerätetreiber" angesehen werden kann:
#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)
Nach dem Build können Sie es verwenden mit:
insmod hello.ko
und es druckt hello init
zu dmesg
.
Es gibt jedoch Kernelmodule, die keine Gerätetreiber sind, aber tatsächlich nützlich sind, z. B. Module, die Kernel-Debugging- / Leistungsinformationen bereitstellen.
Gerätetreiber sind in der Regel auch Kernelmodule.
Ein Beispiel für etwas, das ein "Gerätetreiber" ist, ist etwas schwieriger zu generieren, da es eine Hardware zum Fahren erfordert und Hardwarebeschreibungen in der Regel kompliziert sind.
Mit QEMU oder anderen Emulatoren können wir jedoch Softwaremodelle aus realer oder vereinfachter Hardware erstellen. Dies ist eine hervorragende Möglichkeit, um zu lernen, wie man mit Hardware spricht. Hier ist ein einfaches Beispiel eines minimalen PCI-Gerätetreibers: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c
Wir sehen dann, dass es in x86 bei der Kommunikation mit der Hardware darauf ankommt,
Diese Operationen können im Allgemeinen nicht vom Userland aus durchgeführt werden, wie unter: Was ist der Unterschied zwischen User Space und Kernel Space? Es gibt jedoch einige Ausnahmen: https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space .
Der Kernel bietet dann APIs auf höherer Ebene, um solche Hardware-Interaktionen einfacher und portabler zu machen:
request_irq
Interrupts zu behandeln
ioreadX
und IO-Speicherzuordnung
- noch übergeordnete Schnittstellen für gängige Protokolle wie PCI und USB