GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Was ist der Unterschied zwischen Kerneltreibern und Kernelmodulen?

Ein Kernelmodul ist ein bisschen kompilierter Code, der zur Laufzeit in den Kernel eingefügt werden kann, wie zum Beispiel mit insmod oder modprobe .

Ein Treiber ist ein Stück Code, das im Kernel läuft, um mit einem Hardwaregerät zu kommunizieren. Es "treibt" die Hardware. Fast jede Hardware in Ihrem Computer hat einen zugehörigen Treiber.¹ Ein großer Teil eines laufenden Kernels ist Treibercode.²

Ein Treiber kann statisch in die Kernel-Datei auf der Festplatte eingebaut werden.³ Ein Treiber kann auch als Kernel-Modul eingebaut werden, damit er später dynamisch geladen werden kann. (Und dann vielleicht entladen.)

Die Standardpraxis besteht darin, Treiber nach Möglichkeit als Kernelmodule zu erstellen, anstatt sie statisch mit dem Kernel zu verknüpfen, da dies mehr Flexibilität bietet. Es gibt jedoch gute Gründe dagegen:

  • Manchmal ist ein bestimmter Treiber unbedingt erforderlich, um das System beim Hochfahren zu unterstützen. Aufgrund der initrd-Funktion kommt das nicht so oft vor, wie Sie sich vielleicht vorstellen.

  • Statisch erstellte Treiber können genau das sein, was Sie in einem System mit statischem Geltungsbereich wünschen, wie z. B. einem eingebetteten System. Das heißt, wenn Sie im Voraus genau wissen, welche Treiber immer benötigt werden und dass sich dies nie ändern wird, haben Sie einen guten Grund, sich nicht um dynamische Kernel-Module zu kümmern.

  • Wenn Sie Ihren Kernel statisch erstellen und die dynamische Modulladefunktion von Linux deaktivieren, verhindern Sie Laufzeitänderungen des Kernelcodes. Dies bietet zusätzliche Sicherheit und Stabilität auf Kosten der Flexibilität.

Nicht alle Kernelmodule sind Treiber. Ein relativ neues Feature im Linux-Kernel ist beispielsweise, dass Sie einen anderen Prozess-Scheduler laden können. Ein weiteres Beispiel ist, dass die komplexeren Hardwaretypen oft mehrere generische Schichten haben, die sich zwischen dem Low-Level-Hardwaretreiber und dem Benutzerland befinden, wie z. B. der USB-HID-Treiber, der ein bestimmtes Element des USB-Stacks unabhängig von der zugrunde liegenden Hardware implementiert.

Nebenbei:

  1. Eine Ausnahme von dieser allgemeinen Aussage ist der CPU-Chip, der keinen "Treiber" per se hat . Ihr Computer kann auch Hardware enthalten, für die Sie keinen Treiber haben.

  2. Der Rest des Codes in einem OS-Kernel bietet generische Dienste wie Speicherverwaltung, IPC, Scheduling usw. Diese Dienste können hauptsächlich Userland-Anwendungen dienen, wie bei den zuvor verlinkten Beispielen, oder sie können interne Dienste sein, die von Treibern oder anderen internen Diensten verwendet werden. Kernel-Infrastruktur.

  3. Der in /boot , die beim Booten vom Bootloader zu einem frühen Zeitpunkt des Bootvorgangs in den Arbeitsspeicher geladen werden.


Um Ihre spezielle Frage zu lspci zu beantworten ausgegeben, gibt die Zeile "kernel driver" an, welcher Treiber aktuell an die Karte gebunden ist, in diesem Fall der proprietäre nvidia Treiber. Die Zeile "Kernel Modules" listet alle bekannten Treiber auf an diese Karte binden kann. Hier zeigt der proprietäre Treiber einen anderen Namen an, wahrscheinlich aufgrund von lspci den Treiber und seinen Dateinamen im Vergleich zu dem im Treiber selbst codierten Namen gefunden.


Ein Kernelmodul ist möglicherweise überhaupt kein Gerätetreiber

"Kernel-Treiber" ist kein gut definierter Begriff, aber versuchen wir es mal.

Dies ist ein Kernelmodul, das keine Hardware antreibt und daher vernünftigerweise nicht als "Gerätetreiber" betrachtet 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 bis dmesg .

Es gibt jedoch Kernelmodule, die keine Gerätetreiber sind, aber tatsächlich nützlich sind, z. B. Module, die Kernel-Debugging-/Leistungsinformationen offenlegen.

Gerätetreiber sind normalerweise auch Kernelmodule.

Ein Beispiel für etwas, das ein "Gerätetreiber" ist, ist etwas schwieriger zu generieren, da Hardware zum Ansteuern erforderlich ist und Hardwarebeschreibungen in der Regel kompliziert sind.

Mit QEMU oder anderen Emulatoren können wir jedoch Softwaremodelle echter oder vereinfachter Hardware erstellen, was eine großartige Möglichkeit ist, zu lernen, wie man mit Hardware spricht. Hier ist ein einfaches Beispiel für einen minimalen PCI-Gerätetreiber:https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c

Wir sehen dann, dass in x86 die Kommunikation mit Hardware auf Folgendes hinausläuft:

  • in und out Anweisungen, z. B. https://stackoverflow.com/questions/3215878/what-are-in-out-instructions-in-x86-used-for/33444273#33444273
  • Behandlung von Interrupts durch Registrierung von Handlern bei der CPU

Diese Operationen können im Allgemeinen nicht vom Userland aus durchgeführt werden, wie erklärt 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 eine solche Hardware-Interaktion einfacher und portabler zu machen:

  • request_irq Interrupts behandeln
  • ioreadX und IO-Memory-Mapping
  • noch höherwertige Schnittstellen für gängige Protokolle wie PCI und USB

Linux
  1. Was ist der Unterschied zwischen module_init und init_module in einem Linux-Kernel-Modul?

  2. Was ist der Unterschied zwischen strtok_r und strtok_s in C?

  3. Was ist der Unterschied zwischen einem Linux-Plattformtreiber und einem normalen Gerätetreiber?

  4. Was ist der Unterschied zwischen adduser und useradd?

  5. Was ist der Unterschied zwischen nicht präemptivem, präemptivem und selektivem präemptivem Kernel?

Was ist der Unterschied zwischen InnoDB und MyISAM?

Was ist der Unterschied zwischen macOS- und Linux-Kernels

Was ist der Unterschied zwischen Linux und Unix?

Der Unterschied zwischen [[ $a ==Z* ]] und [ $a ==Z* ]?

Was ist ein Hypervisor? Was ist der Unterschied zwischen Typ 1 und 2?

Was ist der Unterschied zwischen Curl und Wget?