Kernel und Module: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
 
(2 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
=Kernel=
=Kernel=
==Grundlegendes==
==Grundlegendes==
*Der Kernel eines Betriebssystems bildet die hardwareabstrahierende Schicht
*Der Kernel eines Betriebssystems bildet die hardwareabstrahierende Schicht.
*Er stellt auf dieser Basis der aufsetzenden Software eine einheitliche Schnittstelle (API) zur Verfügung.
*Er stellt der aufsetzenden Software eine einheitliche Schnittstelle (API) zur Verfügung.
*Diese agiert unabhängig von der Rechnerarchitektur.
*Diese agiert unabhängig von der Rechnerarchitektur.
*Die Software kann so immer auf die Schnittstelle zugreifen und braucht die Hardware nicht genauer zu kennen.
*Die Software kann so immer auf die Schnittstelle zugreifen und braucht die Hardware nicht genauer zu kennen.
*Linux ist dabei ein modularer monolithischer Kernel.
*Der Kernel ist so etwas wie ein Vermittler zwischen Anwendungsprogrammen und Hardware.
*Der Kernel ist so etwas wie ein Vermittler zwischen Anwendungsprogrammen und Hardware.
*Die Aufgaben sind Speicherverwaltung, Prozessverwaltung, Multitasking, Lastverteilung, Durchsetzung der Berechtigungen und Eingabe/Ausgabe-Operationen auf verschiedenen Geräten.
*Die Aufgaben sind Speicherverwaltung, Prozessverwaltung, Multitasking, Lastverteilung, Durchsetzung der Berechtigungen und Eingabe/Ausgabe-Operationen auf verschiedenen Geräten.
*Der Kernel wird beim Systemstart in den Speicher geladen und verbleibt dort während der ganzen Zeit.
*Der Kernel wird beim Systemstart in den Speicher geladen und verbleibt dort während der ganzen Zeit.
*Der Kern selbst hat keine Anwendungsprogramme, Bibliotheken oder Systemsoftware.
*Der Kern selbst hat keine Anwendungsprogramme, Bibliotheken oder Systemsoftware.
==Monolithischer Kernel und Mikrokernel==
*'''Mikrokernel''' (z.B. QNX, Minix, seL4): Nur das Nötigste läuft im Kernel. Treiber laufen als eigene Prozesse im User Space.
*'''Monolithischer Kernel''': Treiber, Dateisysteme und Netzwerk laufen komplett im Kernel Space.
*Linux ist ein '''modularer monolithischer Kernel'''.
*Er ist monolithisch, kann aber Teile (Module) zur Laufzeit nachladen und entladen.
*Wichtig: Ein geladenes Modul läuft im Kernel Space mit vollen Rechten. Ein fehlerhaftes Modul kann das ganze System mitreißen.
==Schaubild==
==Schaubild==
*Die Anwendungsprogramme greifen nicht direkt auf die Hardware zu.
*Die Anwendungsprogramme greifen nicht direkt auf die Hardware zu.
*Sie rufen Kernel System Calls auf und diese machen dann die wirklichen Aktionen.
*Sie rufen Kernel System Calls auf und diese machen dann die wirklichen Aktionen.
*Der Kernel kann aber auch Aufrufe verweigern.
*Meist geschieht das über die C-Bibliothek (glibc).
*Der Kernel kann Aufrufe auch verweigern (z.B. fehlende Berechtigung).
{{#drawio:kernel-space}}
{{#drawio:kernel-space}}
== Gerätetreiber unter Linux ==
*Ein '''Gerätetreiber''' ist ein spezielles Stück Software, das ein Betriebssystem (wie Linux) mit einer Hardwarekomponente verbindet.
*Jeder Hardwarekomponente benötigt einen spezifischen Treiber, um korrekt zu funktionieren.
*Unter Linux sind viele dieser Treiber als Kernel-Module verfügbar, die dynamisch geladen und entladen werden können.


=== Kernel-Module ===
==Gerätetreiber unter Linux==
;Ein Kernel-Modul ist ein Stück Code, das dynamisch in den Kernel eingefügt werden kann, um zusätzliche Funktionen bereitzustellen. Viele Gerätetreiber sind als Kernel-Module implementiert.  
*Ein '''Gerätetreiber''' ist ein spezielles Stück Software, das ein Betriebssystem (wie Linux) mit einer Hardwarekomponente verbindet.
*Jede Hardwarekomponente benötigt einen spezifischen Treiber, um korrekt zu funktionieren.
*Unter Linux sind die meisten dieser Treiber als Kernel-Module verfügbar, die dynamisch geladen und entladen werden können.
 
=Module=
==Kernel-Module==
;Ein Kernel-Modul ist ein Stück Code, das dynamisch in den Kernel eingefügt werden kann, um zusätzliche Funktionen bereitzustellen.
*Viele Gerätetreiber sind als Kernel-Module implementiert, z.B. WLAN-Karte, Soundkarte, Netzwerkkarte.
*Auch Dateisysteme (z.B. xfs, btrfs) und Netzwerkfunktionen (z.B. nftables) sind oft Module.
*Distributionen wie Debian, Ubuntu oder Rocky nutzen einen "allgemeinen" Kernel und laden passend zur Hardware die nötigen Module.
*In der Regel werden alle notwendigen Module beim Systemstart und bei Bedarf zur Laufzeit automatisch geladen.


=Möglichkeiten=
==Fest im Kernel verankert==
==Fest im Kernel verankert==
*Treiber ist Teil des Original Kernel Quellcode
*Treiber ist Teil des Original-Kernel-Quellcodes.
*Das Modul(Treiber) wurde beim komipilieren fest in den Kernel verankert.
*Das Modul (Treiber) wurde beim Kompilieren fest in den Kernel eingebaut.
*Es lässt sich somit nicht mehr entladen.
*Es lässt sich somit nicht mehr entladen.
*Anwendung gehärteter Kernel
*Anwendung: gehärteter Kernel
*Wenn ich die Netzwerkkarten von meiner Produktionslinie kenne, brauche ich nur diese in den Kernel zu kompilieren.
*Wenn ich die Netzwerkkarten von meiner Produktionslinie kenne, brauche ich nur diese in den Kernel zu kompilieren.
{{#drawio:kernel-und-module-1}}
{{#drawio:kernel-und-module-1}}
==Modul gehört zum Kernel und kann nachgeladen werden.==
 
*Treiber ist Teil des Original Kernel Quellcode
==Modul gehört zum Kernel und kann nachgeladen werden==
*Das Modul wurde beim Kompilieren mit übersetzt.
*Treiber ist Teil des Original-Kernel-Quellcodes.
*Es ist somit Nachladbar.
*Das Modul wurde beim Kompilieren mit übersetzt, aber als eigene Datei (.ko).
*Es ist somit nachladbar.
*Es kann direkt an den Kernel andocken und geht somit eine Symbiose mit dem Kernel ein.
*Es kann direkt an den Kernel andocken und geht somit eine Symbiose mit dem Kernel ein.
*Geöhnliche und verbreitete Treiber sind normalerweise nachladbar.
*Gewöhnliche und verbreitete Treiber sind normalerweise nachladbar.
{{#drawio:kernel-und-module}}
{{#drawio:kernel-und-module}}
==Fest oder Modul? Selbst nachschauen==
*Die Konfiguration des laufenden Kernels liegt unter /boot/config-$(uname -r).
*'''=y''' bedeutet fest eingebaut, '''=m''' bedeutet Modul.
*grep -E "CONFIG_(UNIX|INET|EXT4_FS|XFS_FS)=" /boot/config-$(uname -r)
<pre>
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_EXT4_FS=m
CONFIG_XFS_FS=m
</pre>
*Beispiel Debian 13: Unix-Sockets und IPv4 sind fest drin, selbst ext4 ist ein Modul (es steckt in der initramfs).
*Alle fest eingebauten Treiber stehen in modules.builtin:
*grep tcp_cubic /lib/modules/$(uname -r)/modules.builtin
==Hersteller stellt Quellcode von einem Treiber zur Verfügung==
==Hersteller stellt Quellcode von einem Treiber zur Verfügung==
*Treiber ist nicht Teil des Original Kernel Quellcode
*Treiber ist nicht Teil des Original-Kernel-Quellcodes (out-of-tree).
*Man muss das Modul nun für den passenden Kernel übersetzen.
*Man muss das Modul nun für den passenden Kernel übersetzen.
*Es gibt 2 Möglichkeiten
*Dazu braucht man nicht den kompletten Kernelquellcode, sondern nur die Kernel-Header.
**Debian: linux-headers-$(uname -r)
**Rocky: kernel-devel-$(uname -r)
*Es gibt 2 Möglichkeiten.
 
===Treiber vom Hersteller selbst kompilieren (schlechter)===
===Treiber vom Hersteller selbst kompilieren (schlechter)===
*Quellen des Treibers besorgen.
*Quellen des Treibers besorgen.
*Quellen des aktuellen Kernels installieren
*Kernel-Header des laufenden Kernels installieren.
*Diverse Tools wie make installieren.
*Diverse Tools wie make und gcc installieren.
*Modul gegen den aktuellen Kernel kompilieren
*Modul gegen den aktuellen Kernel kompilieren.
*Nachteil: Bei einem Kernelupdate geht das Spiel erneut los.
*Nachteil: Bei einem Kernelupdate geht das Spiel erneut los.
*Das Modul liegt nur unter /lib/modules/<alte Version> und fehlt dem neuen Kernel.


===DKMS(besser)===
===DKMS (besser)===
*Quellen sind meist über das Paketmanagment erhältlich.
*DKMS = Dynamic Kernel Module Support
*DKMS übersetzt das Modul gegen den laufenden Kernel
*Quellen sind meist über das Paketmanagement erhältlich (Pakete enden oft auf -dkms).
*DKMS übersetzt das Modul gegen den laufenden Kernel.
*Am Schluss ist das Modul verfügbar.
*Am Schluss ist das Modul verfügbar.
*Vorteil: Bei einem Kernelupdate kompiliert DKMS das Modul automatisch.
*Vorteil: Bei einem Kernelupdate kompiliert DKMS das Modul automatisch neu.
*apt install virtualbox-dkms
*dkms status
 
===Secure Boot===
*Ist Secure Boot aktiv, lädt der Kernel nur signierte Module.
*Selbst gebaute und DKMS-Module sind zunächst nicht von der Distribution signiert.
*DKMS erzeugt deshalb einen eigenen Schlüssel (MOK = Machine Owner Key).
*Dieser muss einmalig importiert und beim nächsten Neustart im MOK-Manager bestätigt werden.
*mokutil --sb-state
*mokutil --import /var/lib/dkms/mok.pub
*Typischer Fehler ohne Signatur: '''Key was rejected by service'''


==Effekt==
==Effekt==
*Der Effekt ist bei beiden Verfahren derselbe.
*Der Effekt ist bei beiden Verfahren derselbe.
*Wichtig: Kernel wird nicht neukompiliert.  
*Wichtig: Der Kernel wird nicht neu kompiliert.
*Er wird nur für die richtigen Andockpunkte im Quellcode benötigt.
*Die Header werden nur für die richtigen Andockpunkte im Quellcode benötigt.
{{#drawio:kernel-und-module-2}}
{{#drawio:kernel-und-module-2}}
=Modulverwaltung=
==Installation==
*Die Programme sind in der Standardinstallation enthalten.
*Sie stammen aus dem Paket '''kmod''' (früher module-init-tools).


==Tools==
==Tools==
===Welche Module stellt der laufende Kernel zur Verfügung===
*'''lsmod''': Zeigt geladene Module an
*find /lib/modules/$(uname -r) -name *.ko
*'''modinfo''': Zeigt Informationen über ein Modul an
oder
*'''modprobe''': Lädt und entlädt Module und löst dabei Abhängigkeiten auf
*find /lib/modules/$(uname -r) -name *.ko.xz
*'''insmod''': Lädt eine einzelne Moduldatei über ihren Pfad, ohne Abhängigkeiten aufzulösen
*'''rmmod''': Entlädt ein einzelnes Modul, ohne Abhängigkeiten
*'''depmod''': Erstellt die Dateien zur Auflösung von Modulabhängigkeiten
*Im Alltag nimmt man '''modprobe''' statt insmod und rmmod.


==== Beispiel: Anzeigen geladener Kernel-Module ====
==Ort, wo die Module des laufenden Kernels liegen==
;Die Module des aktuellen Kernels befinden sich im Verzeichnis /lib/modules/$(uname -r).
*Je nach Distribution sind sie komprimiert (.ko.xz oder .ko.zst).
*Die Anführungszeichen sind wichtig, sonst wertet die Shell den Stern selbst aus.
*find /lib/modules/$(uname -r) -name "*.ko*"


==Geladene Module anzeigen==
;Mit dem Befehl '''lsmod''' kann man die aktuell geladenen Module anzeigen lassen.
*lsmod
*lsmod
*Die Spalte "Used by" zeigt, welche anderen Module ein Modul gerade benutzen.


==== Beispiel: Laden eines Kernel-Moduls ====
==Informationen anzeigen==
;Mit dem Befehl '''modinfo''' kann man Informationen zu einem bestimmten Modul anzeigen lassen.
*modinfo usb_common
*Interessant sind filename, depends, parm (Optionen) und signer.


*sudo modprobe modulname
==Module laden und entladen==
;Mit dem Befehl '''modprobe''' können Module zur Laufzeit geladen oder entladen werden.
*modprobe [Optionen] Modulname


==== Beispiel: Entfernen eines Kernel-Moduls ====
;Optionen sind unter anderem:
*'''-v''': Ausführliche Ausgabe
*'''-n''': Simuliert das Laden des Moduls, lädt es aber nicht (sinnvoll zusammen mit -v)
*'''-a''': Lädt alle in der Kommandozeile angegebenen Module
*'''-r''': Entlädt das Modul und nicht mehr benötigte Abhängigkeiten


*sudo rmmod modulname
;Beispiele
*sudo modprobe -v usb_common
*sudo modprobe -n -v xfs
*sudo modprobe -r xfs
*Ein Modul, das gerade benutzt wird, lässt sich nicht entladen.
<pre>
modprobe: FATAL: Module xfs is in use.
</pre>


=== Gerätetreiber installieren ===
==Abhängigkeiten von Modulen==
*Die genaue Methode zur Installation eines Gerätetreibers variiert je nach Treiber und Linux-Distribution.  
;Manche Module können erst geladen werden, wenn andere Module geladen sind, da sie von diesen abhängen.
*Oftmals werden Treiber über den Paketmanager der Distribution installiert.  
*Diese Abhängigkeiten sind in der Datei /lib/modules/$(uname -r)/modules.dep hinterlegt.
*Manchmal müssen Treiber jedoch von der Herstellerseite heruntergeladen und manuell installiert werden.
*depmod erstellt diese Datei neu, z.B. nachdem ein Modul von Hand nach /lib/modules kopiert wurde.
*sudo depmod -a
 
==Modul-Optionen==
*Viele Module haben Parameter, die man mit modinfo sieht.
*Beim Laden: sudo modprobe Modulname parameter=wert
*Dauerhaft in einer Datei unter /etc/modprobe.d/, die auf '''.conf''' endet:
<pre>
options snd_hda_intel power_save=1
</pre>
*Die aktuellen Werte stehen unter /sys/module/<modulname>/parameters/.
 
==Automatisches Laden von Modulen==
*Meist muss man nichts tun.
*Erkennt der Kernel neue Hardware, lädt udev anhand der Geräte-ID (modalias) automatisch den passenden Treiber.
*Module, die trotzdem beim Booten immer geladen werden sollen, trägt man in eine Datei unter /etc/modules-load.d/ ein.
*Die Datei muss auf '''.conf''' enden, ein Modul pro Zeile.
<pre>
# /etc/modules-load.d/lp.conf
lp
</pre>
*Debian liest zusätzlich noch die alte Datei /etc/modules.
 
==Automatisches Laden verhindern - Blacklisting==
*Unter bestimmten Umständen kann es sinnvoll sein, das Laden von bestimmten Modulen zu verbieten.
*Beispiel: Zwei Treiber kommen für dasselbe Gerät in Frage oder ein Treiber macht Probleme.
*Dazu legt man eine Datei im Verzeichnis '''/etc/modprobe.d''' an.
*Der Name ist frei wählbar, die Datei muss aber auf '''.conf''' enden.
*In der Regel sind hier schon einige Dateien zu finden.
 
==Blacklist-Datei==
*cat /etc/modprobe.d/blacklist.conf
<pre>
# This file lists those modules which we don't want to be loaded by
# alias expansion, usually so some other driver will be loaded for the
# device instead.
 
# evbug is a debug tool that should be loaded explicitly
blacklist evbug
 
# these drivers are very simple, the HID drivers are usually preferred
blacklist usbmouse
blacklist usbkbd
...
</pre>


=== Treiberprobleme beheben ===
==Eigene Blacklist anlegen==
Wenn eine Hardwarekomponente nicht korrekt funktioniert, kann es sein, dass der richtige Treiber nicht geladen ist oder Probleme aufweist. Tools wie '''dmesg''' und '''lspci''' können helfen, Treiberprobleme zu identifizieren und zu beheben.
*echo "blacklist pcspkr" | sudo tee /etc/modprobe.d/blacklist-pcspkr.conf


==== Beispiel: Anzeigen von Kernel-Nachrichten mit dmesg ====
==Wichtig==
*blacklist verhindert nur das '''automatische''' Laden.
*Von Hand mit modprobe oder als Abhängigkeit eines anderen Moduls wird es trotzdem geladen.
*Soll ein Modul gar nicht geladen werden können, zusätzlich:
<pre>
install pcspkr /bin/false
</pre>
*Wird das Modul schon in der initramfs geladen, muss diese neu gebaut werden.
**Debian: sudo update-initramfs -u
**Rocky: sudo dracut -f


*dmesg
=Treiberprobleme beheben=
==Gerätetreiber installieren==
*Die genaue Methode zur Installation eines Gerätetreibers variiert je nach Treiber und Linux-Distribution.
*Oftmals werden Treiber über den Paketmanager der Distribution installiert (z.B. firmware-* Pakete oder *-dkms Pakete).
*Manchmal müssen Treiber jedoch von der Herstellerseite heruntergeladen und manuell installiert werden.


==== Beispiel: Anzeigen von PCI-Geräten mit lspci ====
==Welcher Treiber gehört zu welchem Gerät==
;Mit '''lspci -k''' sieht man zu jedem PCI-Gerät den benutzten Treiber.
*lspci -k
<pre>
00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02)
Subsystem: Intel Corporation PRO/1000 MT Desktop Adapter
Kernel driver in use: e1000
Kernel modules: e1000
</pre>
*Fehlt die Zeile '''Kernel driver in use''', ist für das Gerät kein Treiber geladen.
*Für USB-Geräte: lsusb und lsusb -t


*lspci
==Kernel-Nachrichten anzeigen==
;Mit '''dmesg''' sieht man die Meldungen des Kernels, z.B. beim Laden von Treibern oder fehlender Firmware.
*Unter Debian braucht man dafür root-Rechte.
*sudo dmesg
*sudo dmesg -w (live mitlesen)
*journalctl -k
*sudo dmesg | grep -i firmware

Aktuelle Version vom 17. Oktober 2026, 14:08 Uhr

Kernel

Grundlegendes

  • Der Kernel eines Betriebssystems bildet die hardwareabstrahierende Schicht.
  • Er stellt der aufsetzenden Software eine einheitliche Schnittstelle (API) zur Verfügung.
  • Diese agiert unabhängig von der Rechnerarchitektur.
  • Die Software kann so immer auf die Schnittstelle zugreifen und braucht die Hardware nicht genauer zu kennen.
  • Der Kernel ist so etwas wie ein Vermittler zwischen Anwendungsprogrammen und Hardware.
  • Die Aufgaben sind Speicherverwaltung, Prozessverwaltung, Multitasking, Lastverteilung, Durchsetzung der Berechtigungen und Eingabe/Ausgabe-Operationen auf verschiedenen Geräten.
  • Der Kernel wird beim Systemstart in den Speicher geladen und verbleibt dort während der ganzen Zeit.
  • Der Kern selbst hat keine Anwendungsprogramme, Bibliotheken oder Systemsoftware.

Monolithischer Kernel und Mikrokernel

  • Mikrokernel (z.B. QNX, Minix, seL4): Nur das Nötigste läuft im Kernel. Treiber laufen als eigene Prozesse im User Space.
  • Monolithischer Kernel: Treiber, Dateisysteme und Netzwerk laufen komplett im Kernel Space.
  • Linux ist ein modularer monolithischer Kernel.
  • Er ist monolithisch, kann aber Teile (Module) zur Laufzeit nachladen und entladen.
  • Wichtig: Ein geladenes Modul läuft im Kernel Space mit vollen Rechten. Ein fehlerhaftes Modul kann das ganze System mitreißen.

Schaubild

  • Die Anwendungsprogramme greifen nicht direkt auf die Hardware zu.
  • Sie rufen Kernel System Calls auf und diese machen dann die wirklichen Aktionen.
  • Meist geschieht das über die C-Bibliothek (glibc).
  • Der Kernel kann Aufrufe auch verweigern (z.B. fehlende Berechtigung).
kernel-space

Gerätetreiber unter Linux

  • Ein Gerätetreiber ist ein spezielles Stück Software, das ein Betriebssystem (wie Linux) mit einer Hardwarekomponente verbindet.
  • Jede Hardwarekomponente benötigt einen spezifischen Treiber, um korrekt zu funktionieren.
  • Unter Linux sind die meisten dieser Treiber als Kernel-Module verfügbar, die dynamisch geladen und entladen werden können.

Module

Kernel-Module

Ein Kernel-Modul ist ein Stück Code, das dynamisch in den Kernel eingefügt werden kann, um zusätzliche Funktionen bereitzustellen.
  • Viele Gerätetreiber sind als Kernel-Module implementiert, z.B. WLAN-Karte, Soundkarte, Netzwerkkarte.
  • Auch Dateisysteme (z.B. xfs, btrfs) und Netzwerkfunktionen (z.B. nftables) sind oft Module.
  • Distributionen wie Debian, Ubuntu oder Rocky nutzen einen "allgemeinen" Kernel und laden passend zur Hardware die nötigen Module.
  • In der Regel werden alle notwendigen Module beim Systemstart und bei Bedarf zur Laufzeit automatisch geladen.

Fest im Kernel verankert

  • Treiber ist Teil des Original-Kernel-Quellcodes.
  • Das Modul (Treiber) wurde beim Kompilieren fest in den Kernel eingebaut.
  • Es lässt sich somit nicht mehr entladen.
  • Anwendung: gehärteter Kernel
  • Wenn ich die Netzwerkkarten von meiner Produktionslinie kenne, brauche ich nur diese in den Kernel zu kompilieren.
kernel-und-module-1

Modul gehört zum Kernel und kann nachgeladen werden

  • Treiber ist Teil des Original-Kernel-Quellcodes.
  • Das Modul wurde beim Kompilieren mit übersetzt, aber als eigene Datei (.ko).
  • Es ist somit nachladbar.
  • Es kann direkt an den Kernel andocken und geht somit eine Symbiose mit dem Kernel ein.
  • Gewöhnliche und verbreitete Treiber sind normalerweise nachladbar.
kernel-und-module

Fest oder Modul? Selbst nachschauen

  • Die Konfiguration des laufenden Kernels liegt unter /boot/config-$(uname -r).
  • =y bedeutet fest eingebaut, =m bedeutet Modul.
  • grep -E "CONFIG_(UNIX|INET|EXT4_FS|XFS_FS)=" /boot/config-$(uname -r)
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_EXT4_FS=m
CONFIG_XFS_FS=m
  • Beispiel Debian 13: Unix-Sockets und IPv4 sind fest drin, selbst ext4 ist ein Modul (es steckt in der initramfs).
  • Alle fest eingebauten Treiber stehen in modules.builtin:
  • grep tcp_cubic /lib/modules/$(uname -r)/modules.builtin

Hersteller stellt Quellcode von einem Treiber zur Verfügung

  • Treiber ist nicht Teil des Original-Kernel-Quellcodes (out-of-tree).
  • Man muss das Modul nun für den passenden Kernel übersetzen.
  • Dazu braucht man nicht den kompletten Kernelquellcode, sondern nur die Kernel-Header.
    • Debian: linux-headers-$(uname -r)
    • Rocky: kernel-devel-$(uname -r)
  • Es gibt 2 Möglichkeiten.

Treiber vom Hersteller selbst kompilieren (schlechter)

  • Quellen des Treibers besorgen.
  • Kernel-Header des laufenden Kernels installieren.
  • Diverse Tools wie make und gcc installieren.
  • Modul gegen den aktuellen Kernel kompilieren.
  • Nachteil: Bei einem Kernelupdate geht das Spiel erneut los.
  • Das Modul liegt nur unter /lib/modules/<alte Version> und fehlt dem neuen Kernel.

DKMS (besser)

  • DKMS = Dynamic Kernel Module Support
  • Quellen sind meist über das Paketmanagement erhältlich (Pakete enden oft auf -dkms).
  • DKMS übersetzt das Modul gegen den laufenden Kernel.
  • Am Schluss ist das Modul verfügbar.
  • Vorteil: Bei einem Kernelupdate kompiliert DKMS das Modul automatisch neu.
  • apt install virtualbox-dkms
  • dkms status

Secure Boot

  • Ist Secure Boot aktiv, lädt der Kernel nur signierte Module.
  • Selbst gebaute und DKMS-Module sind zunächst nicht von der Distribution signiert.
  • DKMS erzeugt deshalb einen eigenen Schlüssel (MOK = Machine Owner Key).
  • Dieser muss einmalig importiert und beim nächsten Neustart im MOK-Manager bestätigt werden.
  • mokutil --sb-state
  • mokutil --import /var/lib/dkms/mok.pub
  • Typischer Fehler ohne Signatur: Key was rejected by service

Effekt

  • Der Effekt ist bei beiden Verfahren derselbe.
  • Wichtig: Der Kernel wird nicht neu kompiliert.
  • Die Header werden nur für die richtigen Andockpunkte im Quellcode benötigt.
kernel-und-module-2

Modulverwaltung

Installation

  • Die Programme sind in der Standardinstallation enthalten.
  • Sie stammen aus dem Paket kmod (früher module-init-tools).

Tools

  • lsmod: Zeigt geladene Module an
  • modinfo: Zeigt Informationen über ein Modul an
  • modprobe: Lädt und entlädt Module und löst dabei Abhängigkeiten auf
  • insmod: Lädt eine einzelne Moduldatei über ihren Pfad, ohne Abhängigkeiten aufzulösen
  • rmmod: Entlädt ein einzelnes Modul, ohne Abhängigkeiten
  • depmod: Erstellt die Dateien zur Auflösung von Modulabhängigkeiten
  • Im Alltag nimmt man modprobe statt insmod und rmmod.

Ort, wo die Module des laufenden Kernels liegen

Die Module des aktuellen Kernels befinden sich im Verzeichnis /lib/modules/$(uname -r).
  • Je nach Distribution sind sie komprimiert (.ko.xz oder .ko.zst).
  • Die Anführungszeichen sind wichtig, sonst wertet die Shell den Stern selbst aus.
  • find /lib/modules/$(uname -r) -name "*.ko*"

Geladene Module anzeigen

Mit dem Befehl lsmod kann man die aktuell geladenen Module anzeigen lassen.
  • lsmod
  • Die Spalte "Used by" zeigt, welche anderen Module ein Modul gerade benutzen.

Informationen anzeigen

Mit dem Befehl modinfo kann man Informationen zu einem bestimmten Modul anzeigen lassen.
  • modinfo usb_common
  • Interessant sind filename, depends, parm (Optionen) und signer.

Module laden und entladen

Mit dem Befehl modprobe können Module zur Laufzeit geladen oder entladen werden.
  • modprobe [Optionen] Modulname
Optionen sind unter anderem
  • -v: Ausführliche Ausgabe
  • -n: Simuliert das Laden des Moduls, lädt es aber nicht (sinnvoll zusammen mit -v)
  • -a: Lädt alle in der Kommandozeile angegebenen Module
  • -r: Entlädt das Modul und nicht mehr benötigte Abhängigkeiten
Beispiele
  • sudo modprobe -v usb_common
  • sudo modprobe -n -v xfs
  • sudo modprobe -r xfs
  • Ein Modul, das gerade benutzt wird, lässt sich nicht entladen.
modprobe: FATAL: Module xfs is in use.

Abhängigkeiten von Modulen

Manche Module können erst geladen werden, wenn andere Module geladen sind, da sie von diesen abhängen.
  • Diese Abhängigkeiten sind in der Datei /lib/modules/$(uname -r)/modules.dep hinterlegt.
  • depmod erstellt diese Datei neu, z.B. nachdem ein Modul von Hand nach /lib/modules kopiert wurde.
  • sudo depmod -a

Modul-Optionen

  • Viele Module haben Parameter, die man mit modinfo sieht.
  • Beim Laden: sudo modprobe Modulname parameter=wert
  • Dauerhaft in einer Datei unter /etc/modprobe.d/, die auf .conf endet:
options snd_hda_intel power_save=1
  • Die aktuellen Werte stehen unter /sys/module/<modulname>/parameters/.

Automatisches Laden von Modulen

  • Meist muss man nichts tun.
  • Erkennt der Kernel neue Hardware, lädt udev anhand der Geräte-ID (modalias) automatisch den passenden Treiber.
  • Module, die trotzdem beim Booten immer geladen werden sollen, trägt man in eine Datei unter /etc/modules-load.d/ ein.
  • Die Datei muss auf .conf enden, ein Modul pro Zeile.
# /etc/modules-load.d/lp.conf
lp
  • Debian liest zusätzlich noch die alte Datei /etc/modules.

Automatisches Laden verhindern - Blacklisting

  • Unter bestimmten Umständen kann es sinnvoll sein, das Laden von bestimmten Modulen zu verbieten.
  • Beispiel: Zwei Treiber kommen für dasselbe Gerät in Frage oder ein Treiber macht Probleme.
  • Dazu legt man eine Datei im Verzeichnis /etc/modprobe.d an.
  • Der Name ist frei wählbar, die Datei muss aber auf .conf enden.
  • In der Regel sind hier schon einige Dateien zu finden.

Blacklist-Datei

  • cat /etc/modprobe.d/blacklist.conf
# This file lists those modules which we don't want to be loaded by
# alias expansion, usually so some other driver will be loaded for the
# device instead.

# evbug is a debug tool that should be loaded explicitly
blacklist evbug

# these drivers are very simple, the HID drivers are usually preferred
blacklist usbmouse
blacklist usbkbd
...

Eigene Blacklist anlegen

  • echo "blacklist pcspkr" | sudo tee /etc/modprobe.d/blacklist-pcspkr.conf

Wichtig

  • blacklist verhindert nur das automatische Laden.
  • Von Hand mit modprobe oder als Abhängigkeit eines anderen Moduls wird es trotzdem geladen.
  • Soll ein Modul gar nicht geladen werden können, zusätzlich:
install pcspkr /bin/false
  • Wird das Modul schon in der initramfs geladen, muss diese neu gebaut werden.
    • Debian: sudo update-initramfs -u
    • Rocky: sudo dracut -f

Treiberprobleme beheben

Gerätetreiber installieren

  • Die genaue Methode zur Installation eines Gerätetreibers variiert je nach Treiber und Linux-Distribution.
  • Oftmals werden Treiber über den Paketmanager der Distribution installiert (z.B. firmware-* Pakete oder *-dkms Pakete).
  • Manchmal müssen Treiber jedoch von der Herstellerseite heruntergeladen und manuell installiert werden.

Welcher Treiber gehört zu welchem Gerät

Mit lspci -k sieht man zu jedem PCI-Gerät den benutzten Treiber.
  • lspci -k
00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02)
	Subsystem: Intel Corporation PRO/1000 MT Desktop Adapter
	Kernel driver in use: e1000
	Kernel modules: e1000
  • Fehlt die Zeile Kernel driver in use, ist für das Gerät kein Treiber geladen.
  • Für USB-Geräte: lsusb und lsusb -t

Kernel-Nachrichten anzeigen

Mit dmesg sieht man die Meldungen des Kernels, z.B. beim Laden von Treibern oder fehlender Firmware.
  • Unter Debian braucht man dafür root-Rechte.
  • sudo dmesg
  • sudo dmesg -w (live mitlesen)
  • journalctl -k
  • sudo dmesg | grep -i firmware