Jaka jest różnica między sterownikami jądra a modułami jądra?


66

Kiedy robię a lspci -kna moim Kubuntu z jądrem generycznym 3.2.0-29, widzę coś takiego:

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

Jest to sterownik jądra nvidiai moduły jądra nvidia_current, nouveau, nvidiafb.

Teraz zastanawiałem się, jaka może być różnica między sterownikami jądra a modułami jądra?

Odpowiedzi:


78

Moduł jądra to trochę skompilowanego kodu, który można wstawić do jądra w czasie wykonywania, na przykład za pomocą insmodlub modprobe.

Sterownik to trochę kodu, który działa w jądrze, aby komunikować się z jakimś urządzeniem sprzętowym. To „napędza” sprzęt. Większość każdego sprzętu w komputerze ma powiązany sterownik .¹ Duża część uruchomionego jądra to kod sterownika .²

Sterownik można wbudować statycznie w plik jądra na dysku .³ Sterownik można również wbudować jako moduł jądra, aby można go było później dynamicznie ładować. (A potem może rozładowany.)

Standardową praktyką jest budowanie sterowników jako modułów jądra tam, gdzie to możliwe, zamiast łączenia ich statycznie z jądrem, ponieważ daje to większą elastyczność. Istnieją jednak dobre powody, aby nie:

  • Czasami dany sterownik jest absolutnie niezbędny do uruchomienia systemu. To nie zdarza się tak często, jak można sobie wyobrazić, ze względu na funkcję initrd .

  • Sterowniki zbudowane statycznie mogą być dokładnie tym, czego potrzebujesz w systemie o statycznym zasięgu, takim jak system wbudowany . To znaczy, jeśli wiesz z góry, które sterowniki będą zawsze potrzebne i że to się nigdy nie zmieni, masz dobry powód, aby nie zawracać sobie głowy dynamicznymi modułami jądra.

  • Jeśli zbudujesz jądro statycznie i wyłączysz funkcję dynamicznego ładowania modułu Linuxa, zapobiegniesz modyfikacji kodu jądra w czasie wykonywania. Zapewnia to dodatkowe bezpieczeństwo i stabilność kosztem elastyczności.

Nie wszystkie moduły jądra są sterownikami. Na przykład stosunkowo nową funkcją jądra systemu Linux jest to, że można załadować inny program do planowania procesów . Innym przykładem jest to, że bardziej złożone typy sprzętu często mają wiele ogólnych warstw, które znajdują się między sterownikiem sprzętowym niskiego poziomu a obszarem użytkownika, takim jak sterownik USB HID , który implementuje określony element stosu USB , niezależnie od leżącego pod nim sprzętu.


Oprócz:

  1. Jedynym wyjątkiem od tej szerokiej oświadczenia jest chip procesora, który ma „kierowca” per se . Twój komputer może również zawierać sprzęt, dla którego nie masz sterownika.

  2. Reszta kodu w jądrze systemu operacyjnego zapewnia ogólne usługi, takie jak zarządzanie pamięcią , IPC , planowanie itp. Usługi te mogą przede wszystkim obsługiwać aplikacje dla obszarów użytkownika , tak jak w przypadku przykładów wcześniej połączonych, lub mogą być usługami wewnętrznymi używanymi przez sterowniki lub inne aplikacje wewnętrzne infrastruktura jądra.

  3. Jeden w /boot, ładowany do pamięci RAM w czasie uruchamiania przez moduł ładujący na początku procesu rozruchu .


1
Moduły mogą być systemami plików, protokołami sieciowymi, funkcjami zapory i wieloma innymi. Niektóre urządzenia (np. Karty Wi-Fi) wymagają stosu modułów, niektóre oferują ogólną infrastrukturę, a inne same sprzęt.
vonbrand,

1
Jest to dobry ogólny zarys, ale miałem dokładnie to samo pytanie co OP, potem natknąłem się na tę odpowiedź i wciąż nie wiedziałem, dlaczego „używany sterownik” różni się od „modułów”. Natomiast odpowiedź @Jima Parisa jest poprawna. Od man lspci: „-k Pokaż sterowniki jądra obsługujące każde urządzenie, a także moduły jądra zdolne do obsługi ”. Można to przeczytać jako: „Pokaż sterownik aktualnie / faktycznie obsługujący urządzenie, a także wszystkie moduły, które mogłyby / powinny go obsługiwać ”.
Binarus

Jeśli znasz system Windows: moduł jest bardzo podobny do biblioteki DLL. W Uniksie moduł jest podobny do obiektu współdzielonego, ale moduł jest przeznaczony tylko dla jądra. Dynamicznie połączony moduł może zawierać sterowniki. Jądro może zawierać statycznie połączone sterowniki. Moduł różni się od DLL (lub .so), ponieważ jądro ma określone wymagania dotyczące dynamicznego ładowania rzeczy.
robocat

18

Aby odpowiedzieć na konkretne pytanie dotyczące lspciwyniku, wiersz „sterownik jądra” odnosi się do tego, który sterownik jest aktualnie związany z kartą, w tym przypadku jest to zastrzeżony nvidiasterownik. W wierszu „modułów jądra” wymieniono wszystkie sterowniki, o których wiadomo, że mogą łączyć się z tą kartą. Tutaj zastrzeżony sterownik pokazuje inną nazwę, prawdopodobnie ze względu na sposób lspciznalezienia sterownika i jego nazwy pliku w porównaniu z nazwą zakodowaną w samym sterowniku.


Dzięki - to pomogło. Gdybym tylko wydał man lspci- mówi dokładnie to, co napisałeś.
Binarus

5

Zgodnie z tym ładnym samouczkiem :

... jednym typem modułu jest sterownik urządzenia, który umożliwia jądrze dostęp do sprzętu podłączonego do systemu.

Tak więc, jeśli spróbujemy narysować drzewo, będziemy mieli „sterownik urządzenia”, który dziedziczy (rozszerza) moduł i który ma bardziej specyficzne cechy, między którymi znajdujemy „dostęp do sprzętu” ...


Jest to tylko częściowo poprawne. Sterownik jest przedmiotem klasy w hierarchii (tak, wewnętrzny projekt Linuksa, podobnie jak większość obecnych systemów operacyjnych, jest zorientowany obiektowo). Ale wspomniany sterownik może być modułem (ładowanym w czasie wykonywania) lub skompilowanym w jądrze. Nie ma (lub bardzo mało) różnicy między alternatywami, jeśli chodzi o kod.
vonbrand,

4

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 initdo 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

0

Moja odpowiedź pójdzie z Jimem. Sterownik jądra to program (moduł jądra) przeznaczony do sterowania sprzętem. Wyjście lspci mówi, że nvidia jest sterownikiem jądra, ponieważ jest loadedmodułem dla urządzenia. Wraz z nim dostępne są inne dostępne moduły jądra.

Dodam, że polecenia w linux do listy i usunąć kierowcy lsmodi rmmododpowiednio. Który mówi moduł listy i usuń moduł.


0

Wszystkie sterowniki są modułami. Nie wszystkie moduły są sterownikami.

Moduły można wstawiać w czasie wykonywania. Moduły / sterowniki mogą być również kompilowane statycznie wraz z jądrem.

Typowy moduł init ma

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

Ten sam moduł może być sterownikiem

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

8
Sterowniki nie zawsze są modułami, mogą być zawarte w głównym obrazie jądra.
Gilles

3
@Prabagaran: „Wszystkie sterowniki są modułami. Wszystkie moduły nie są sterownikami”. To jest sprzeczne. W kategoriach matematycznych to, co mówisz, to D -> M i M ->! D. Pozwala to na D i! D.
Francesco Turco,

2
Myślę, że ma na myśli „Wszystkie sterowniki to moduły. Nie wszystkie moduły to sterowniki”.
Renan,

4
@Renan: To byłoby poprawne, ale jeśli spojrzysz na historię edycji tej odpowiedzi, ktoś już próbował naprawić błąd, a autor go cofnął. Zwykle po prostu edytuję, aby naprawić błąd i przechodzę dalej, ale w tym przypadku mam -1 ', ponieważ jest to po prostu błąd i mylący problem.
Caleb

Z tego co pamiętam (od dawna nie wygłupiałem) jest kilka sterowników, których nie można zbudować jako modułów do załadowania. Wydaje mi się, że pamiętam inne, które można traktować tylko jako moduły.
vonbrand,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.