Модуль ядра може взагалі не бути драйвером пристрою.
"Драйвер ядра" - це не чітко визначений термін, але давайте спробуємо.
Це модуль ядра, який не управляє жодним обладнанням, і тому його не можна розумно вважати "драйвером пристрою":
#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)
Після складання ви можете використовувати його з:
insmod hello.ko
і він друкує hello init
до dmesg
.
Однак є модулі ядра, які не є драйверами пристроїв, але фактично є корисними, наприклад, модулі, що розкривають інформацію про налагодження / продуктивність ядра.
Драйвери пристрою зазвичай також є модулями ядра.
Приклад чогось, що є "драйвером пристрою", генерувати трохи складніше, оскільки для управління ним потрібне обладнання, а описи апаратних засобів, як правило, є складними.
Однак, використовуючи QEMU або інші емулятори, ми можемо побудувати програмні моделі реального або спрощеного обладнання, що є прекрасним способом навчитися спілкуватися з обладнанням. Ось простий приклад мінімального драйвера пристрою PCI: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c
Потім ми бачимо, що в x86 розмова з обладнанням зводиться до:
Ці операції взагалі не можна виконувати з користувальницької області, як це пояснено в: Яка різниця між простором користувача та простором ядра? Однак є деякі винятки: https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space .
Потім ядро пропонує API більш високого рівня, щоб зробити таку апаратну взаємодію простішою та портативнішою:
request_irq
обробляти переривання
ioreadX
і IO картування пам'яті
- ще більш високого рівня інтерфейси для популярних протоколів, таких як PCI та USB