Чим відрізняються драйвери ядра від модулів ядра?


66

Коли я роблю lspci -kна своєму Kubuntu з загальним ядром 3.2.0-29, я можу побачити щось подібне:

01:00.0 VGA compatible controller: NVIDIA Corporation G86 [Quadro NVS 290] (rev a1)
    Subsystem: NVIDIA Corporation Device 0492
    Kernel driver in use: nvidia
    Kernel modules: nvidia_current, nouveau, nvidiafb

Існує драйвер ядра nvidiaі модулів ядра nvidia_current, nouveau, nvidiafb.

Тепер я задумався, яка може бути різниця між драйверами Kernel та модулями Kernel?

Відповіді:


78

Модуль ядра - це трохи складений код, який можна вставити в ядро ​​під час виконання, наприклад, з insmodабо modprobe.

Драйвер - це трохи коду, який працює в ядрі для спілкування з деяким апаратним пристроєм. Він "приводить в рух" обладнання. Більшість апаратних засобів на вашому комп'ютері мають відповідний драйвер. ¹ Значна частина запущеного ядра - це код драйвера

Драйвер може бути вбудований статично у файл ядра на диску. (І тоді, можливо, вивантажений.)

Стандартна практика полягає в тому, щоб побудувати драйвери як модулі ядра, де це можливо, а не прив'язувати їх статично до ядра, оскільки це дає більшу гнучкість. Однак є вагомі причини цього не робити:

  • Іноді даний драйвер абсолютно необхідний, щоб допомогти завантажувати систему. Це відбувається не так часто, як ви можете собі уявити, завдяки функції initrd .

  • Статично вбудовані драйвери можуть бути саме тим, що вам потрібно в системі, яка має статичний обсяг, наприклад, вбудованою системою . Тобто, якщо ви заздалегідь знаєте, які саме драйвери завжди знадобляться, і це ніколи не зміниться, у вас є вагома причина не турбуватися з динамічними модулями ядра.

  • Якщо ви будуєте ядро ​​статично і відключаєте функцію динамічного завантаження динамічного модуля Linux, ви запобігаєте зміні коду ядра під час виконання. Це забезпечує додаткову безпеку та стабільність за рахунок гнучкості.

Не всі модулі ядра є драйверами. Наприклад, відносно недавня функція ядра Linux полягає в тому, що ви можете завантажити інший планувальник процесів . Іншим прикладом є те, що більш складні типи апаратних засобів часто мають декілька загальних шарів, які розташовані між драйвером апаратного забезпечення низького рівня та користувальницькою користувачем, наприклад, драйвер USB HID , який реалізує певний елемент USB-стеку , незалежно від базового обладнання.


Убік:

  1. Один виняток із цього широкого твердження - це мікросхема процесора, яка сама по собі не має "драйвера" . Ваш комп'ютер також може містити обладнання, для якого у вас немає драйвера.

  2. Інша частина коду ядра ОС надає загальні послуги , такі як управління пам'яттю , IPC , планування і т.д. Ці послуги можуть в першу чергу служити призначеного для користувача рівня додатків, як і приклади пов'язані раніше, або вони можуть бути внутрішні послуги , що використовуються водіями або іншими внутрішньо- інфраструктура ядра.

  3. Вхід /boot, завантажений у оперативну пам’ять під час завантаження завантажувачем на початку процесу завантаження .


1
Модулями можуть бути файлові системи, мережеві протоколи, функціонування брандмауера та багато іншого. Для деяких апаратних засобів (наприклад, WiFi-карт) потрібна купа модулів, деякі пропонують загальну інфраструктуру, а інші обробляють саме обладнання.
vonbrand

1
Це хороший загальний контур, але у мене було точно те саме питання, що і в ОП, тоді я натрапив на цю відповідь і досі не знав, чому "драйвер у користуванні" відрізняється від "модулів". На противагу цьому відповідь @Jim Paris Paris правильна. З man lspci: "-k Показати драйвери ядра, що обробляють кожен пристрій, а також модулі ядра, здатні керувати ним." Ви можете прочитати це як: "Показати драйвер, який зараз / фактично керує пристроєм, а також усі модулі, які могли / повинні поводитися з ним".
Бінарус

Якщо ви знаєте windows: Модуль дуже схожий на DLL. У unix модуль схожий на спільний об'єкт, але модуль призначений лише для ядра. Динамічно пов'язаний модуль може містити драйвери. Ядро може містити статично пов'язані драйвери. Модуль відрізняється від DLL (або .so) тим, що ядро ​​має конкретні вимоги щодо того, як динамічно завантажуються речі.
robocat

18

Щоб відповісти на ваше конкретне запитання щодо lspciвиводу, рядок "драйвер ядра" посилається на те, який драйвер зараз пов'язаний з карткою, в даному випадку - власним nvidiaдрайвером. У рядку "модулі ядра" перераховані всі драйвери, які, як відомо, здатні прив’язатись до цієї карти. Тут власний драйвер показує йому інше ім’я, ймовірно, через те, як lspciзнайдений драйвер та його ім'я файлу порівняно з ім'ям, закодованим у сам драйвер.


Спасибі - це допомогло. Якби я лише видав man lspci- там точно сказано те, що ви написали.
Бінарус

5

Відповідно до цього приємного підручника :

... одним із типів модуля є драйвер пристрою, який дозволяє ядру отримати доступ до апаратного забезпечення, підключеного до системи.

Отже, якщо ми спробуємо намалювати дерево, у нас з'явиться "Драйвер пристрою", який успадковує (розширює) Модуль, і який має більш конкретні характеристики, між якими ми знаходимо "доступ до обладнання" ...


Це лише частково правильно. Драйвер є об’єктом класу в ієрархії (так, внутрішня конструкція Linux, як і більшість сучасних операційних систем, орієнтована на об'єкти). Але вказаний драйвер може бути модулем (завантажуваним під час виконання) або компільованим у ядро. Не існує (або дуже мало) різниці між альтернативами, кодовим чином.
vonbrand

4

Модуль ядра може взагалі не бути драйвером пристрою.

"Драйвер ядра" - це не чітко визначений термін, але давайте спробуємо.

Це модуль ядра, який не управляє жодним обладнанням, і тому його не можна розумно вважати "драйвером пристрою":

#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

0

Моя відповідь піде з Джимом. Драйвер ядра - це програма (модуль ядра), призначена для керування частиною обладнання. Вихід lspci говорить, що nvidia є драйвером ядра, оскільки це loadedмодуль для пристрою. Поряд з ним поставляються інші доступні модулі ядра.

Додам, що команди в Linux для переліку та видалення драйверів є lsmodі rmmodвідповідно. Що говорить модуль списку та модуль видалення.


0

Усі драйвери - це модулі. Не всі модулі є драйверами.

Модулі можна вставляти під час виконання. Модулі / драйвери також можуть статично компілюватися разом з ядром.

Типовий модуль init має

module_init(init_fn);
init_fn()
{
   /* some code */
}

Цей же модуль може бути зроблений драйвером

module_init(init_fn);
init_fn()
{
   device_register(&device);
   /* some code */
}

8
Драйвери не завжди є модулями, їх можна включити в основне зображення ядра.
Жиль

3
@Prabagaran: "Усі драйвери є модулями. Усі модулі не є драйверами." Це суперечливо. Математично кажучи, те, що ви говорите, - D -> M і M ->! D. Це дозволяє D і! D.
Франческо Турко

2
Я думаю, що він означає "Всі драйвери - це модулі. Не всі модулі - це драйвери".
Ренан

4
@Renan: Це було б правильно, але якщо ви подивитесь на історію редагування цієї відповіді, хтось уже намагався виправити помилку, і автор її відмінив. Зазвичай я просто редагую, щоб виправити помилку і продовжувати роботу, але в цьому випадку я отримав -1, тому що це просто неправильно і заплутало проблему.
Калеб

Як я пам’ятаю (не обдурили себе деякий час), є деякі драйвери, які не можна побудувати як завантажувані модулі. Здається, я пам’ятаю інших, які можна обробляти лише модулями.
vonbrand
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.