7.4. Umgang mit Geräten und Modulen an einem LFS-System

In Kapitel 6 haben Sie das Paket Udev installiert. Bevor wir zu den Details kommen, wie das alles funktioniert, ein kleiner Rückblick, wie früher mit Geräten umgegangen wurde.

Traditionell benutzte Linux eine statische Methode, bei der sehr viele Gerätedateien vorab unter /dev installiert wurden (manchmal mehrere tausend). Dabei war es völlig egal, ob die dazugehörige Hardware tatsächlich existierte oder nicht. Dies wurde typischerweise durch das Skript MAKEDEV erledigt, welches eine Menge Systemaufrufe mit dem Programm mknod und den entsprechenden Gerätenummern durchführte und so Gerätedateien zu allen möglichen Geräten erzeugte, die es auf der Welt gibt. Mit der Udev-Methode werden nur die Gerätedateien erzeugt, zu denen der Kernel auch ein Gerät gefunden hat. Weil diese Gerätedateien bei jedem Systemstart neu erzeugt werden, werden sie auf einem ramfs-Dateisystem gespeichert. Das ist ein Dateisystem, das nur im Arbeitsspeicher existiert und keinen Festplattenplatz verbraucht. Gerätedateien benötigen kaum Platz, so dass nur sehr wenig Arbeitsspeicher verbraucht wird.

7.4.1. Geschichtliches

Im Februar 2000 wurde ein neues Dateisystem mit dem Namen devfs in den Kernel 2.3.46 integriert und wurde in der 2.4er Serie der stabilen Kernel verfügbar gemacht. Obwohl es in den Kernelquellen selbst verfügbar war, hat diese Methode nie wirkliche Unterstützung von den Kernel-Entwicklern bekommen.

Das Haupt-Problem bei diesem von devfs adaptierten Ansatz war der Weg, wie Geräte erkannt, erzeugt und benannt wurden. Letzteres (Namensvergabe) war wohl das kritischste Problem. Das Dateisystem devfs litt ausserdem unter sog. Race conditions die mit dem Konzept zusammenhingen und nicht ohne nennenswerte Änderungen am Kernel geändert werden konnten. Ausserdem wurde es als „missbilligt“ markiert, weil es aktuell nicht mehr gepflegt wurde.

Mit der Enticklung der 2.5er Entwickler-Kernelserie, die später als 2.6er Serie stabil veröffentlicht wurde, wurde ein neues Dateisystem mit dem Namen sysfs eingeführt. Die Aufgabe von sysfs ist es, die Systemstruktur an die Anwenderprozesse zu exportieren. Mit dieser aus der Anwenderschicht sichtbaren Repräsentation der Systemstruktur wurde ein Ersatz für devfs realistisch.

7.4.2. Udev-Implementierung

Das Dateisystem sysfs wurde oben schon kurz erwähnt. Man fragt sich vielleicht, woher sysfs von den Geräten in einem System weis und welche Gerätenummern verwendet werden müssen. Treiber, die direkt in den Kernel integriert wurden, registrieren sich am sysfs sobald sie vom Kernel erkannt werden. Bei Kernel-Modulen geschieht dieser Vorgang beim Laden des Moduls. Sobald sysfs (unter /sys) in das System eingehängt ist, sind die Daten von den mit sysfs registrierten Treibern für Prozesse aus der Anwenderschicht, und damit auch für udev, verfügbar.

Das Initskript S10udev kümmert sich darum, diese Gerätedateien beim Systemstart zu erzeugen. Das Skript beginnt damit, /sbin/udev als Programm zur Verarbeitung von Hotplug-Ereignissen zu registrieren. In dieser Phase sollten noch keine Hotplug-Ereignisse (wird weiter unten erklärt) generiert werden, aber udev wird für den Fall der Fälle doch schon mal registriert, falls doch Ereignisse auftreten. Das Programm udevstart durchsucht dann das Dateisystem unter /sys und erzeugt die entsprechenden passenden Gerätedateien in /dev. Zum Beispiel enthält /sys/class/tty/vcs/dev die Zeichenkette „7:0“. Diese Zeichenkette wird von udevstart benutzt, um /dev/vcs mit der Hohen Nummer 7 und der niedrigen Nummer 0 zu erzeugen. Die Rechte eines jeden Gerätes entnimmt udevstart den Dateien aus dem Ordner /etc/udev.d/permissions.d/. Diese Dateien sind ähnlich durchnummeriert wie die LFS Bootskripte. Falls udev für eine Gerätedatei keine Datei mit Berechtigungen finden kann, wird die Voreinstellung 600 und der Besitzer root:root festgelegt. Die Namen der Gerätedateien in /dev werden durch Regeln aus /etc/udev/rules.d/ festgelegt.

Sobald die obige Phase abgeschlossen ist, sind alle Geräte die schon existierten und für die Treiber in den Kernel fest eingebaut sind, verfügbar und können benutzt werden. Doch was ist mit den Geräten, die modulare Treiber haben?

Weiter oben wurde das Konzept der „Verarbeitung von Hotplug-Ereignissen“ angesprochen. Wenn vom Kernel eine neue Verbindung mit einem Gerät erkannt wird, erzeugt der Kernel ein sog. Hotplug-Ereignis und schaut in der Datei /proc/sys/kernel/hotplug nach dem Programm, das die Einbindung des neuen Gerätes vornimmt. Das Initskript udev hat udev als Programm zur Verarbeitung von Hotplug-Ereignissen registriert. Wenn also solche Hotplug-Ereignisse erzeugt werden, teilt der Kenel udev mit, in /sys nach den Informationen zu diesem neuen Gerät zu schauen und udev erzeugt dann die dazu passende Gerätedatei in /dev.

Das führt uns zu dem Problem mit udev, das in ähnlicher Form auch schon in devfs existierte. Es wird umgangssprachlich als das „Henne und Ei“ Problem bezeichnet. Die meisten Linux-Distributionen laden Module über Ihre Einträge in /etc/modules.conf. Das Laden eines Moduls wird durch den Zugriff auf die zugehörige Gerätedatei veranlasst. Mit udev funktioniert diese Methode aber nicht, weil die Gerätedatei nicht existiert solange das Modul noch nicht geladen ist. Um dieses Problem zu lösen, wurde das Skript S05modules zusammen mit /etc/sysconfig/modules den LFS-Bootskripten hinzugefügt. Alle in der Datei modules eingetragenen Module werden beim Systemstart geladen. Das ermöglicht udev, Geräte zu erkennen und die entsprechenden Gerätedateien zu erzeugen.

Beachten Sie, dass manche Treiber sehr viele Gerätedateien erzeugen. Auf langsamen Maschinen kann dieser Vorgang ein paar Sekunden dauern. Das bedeutet, dass einige Geräte nicht sofort verfügbar sind.

7.4.3. Umgang mit Hotplug-Geräten/dynamischen Geräten

Wenn Sie ein Gerät anschließen, wie z. B. einen Universal Serial Bus (USB) MP3-Player, dann erkennt der Kernel dieses neue Gerät und erzeugt ein Hotplug-Ereignis. Wenn der Treiber bereits geladen ist (z. B. weil er bereits in den Kernel einkompiliert ist oder bereits durch S05modules geladen wurde), wird udev aufgerufen um die nötigen Gerätedateien mit den Daten aus dem sysfs-Dateisystem in /sys zu erzeugen. Wenn der Treiber für das neue Gerät als Modul verfügbar, aber zur Zeit noch nicht geladen ist, dann wird der Kernel nur ein Hotplug-Ereignis erzeugen, welches die Anwenderschicht über das neue Gerät informiert und das es noch keinem Treiber zugeordnet ist. Sonst passiert nichts weiter und das Gerät ist noch nicht benutzbar.

Wenn Sie ein System erstellen, das sehr viele Treiber als Modul vorhält, dann ist die Methode über S05modules nicht sehr praktikabel. In diesem Fall filft das Paket Hotplug weiter (zu finden unter http://linux-hotplug.sourceforge.net/) Wenn das Hotplug-Paket installiert ist, reagiert es auf die zuvor erwähnten Hotplug-Ereignisse des Bus-Treibers. Hotplug wird die nötigen Module laden und die Geräte durch Erstellen der entsprechenden Gerätedateien zur Verfügung stellen.

7.4.4. Probleme mit dem Erzeugen von Gerätedateien

Es gibt ein paar bekannte Probleme beim automatisierten Erzeugen von Gerätedateien:

1) Ein Kerneltreiber exportiert seine Daten möglicherweise nicht in das sysfs-Dateisystem.

Dieses Problem tritt meist auf, wenn ein Treiber nicht aus dem Kernel-Baum sondern von einem Drittanbieter kommt. Für dieses Treiber wird schlussendlich keine Gerätedatei erzeugt. Verwenden Sie die Datei /etc/sysconfig/createfiles um die Gerätedateien manuell zu erzeugen. Ziehen Sie die Datei devices.txt aus dem Quellbaum des Kernels zu Rate, oder lesen Sie die Dokumentation zu dem Treiber um die passenden hohen und niedrigen Nummern der Gerätedatei herauszufinden.

2) Es wird ein Gerät benötigt, das keine Hardware ist. Auf dieses Problem werden Sie meist stoßen, wenn Sie ALSA's (Advanced Linux Sound Architecture) OSS-Kompatibilitätsmodule verwenden. Dieser Gerätetyp kann mit einer dieser zwei Möglichkeiten eingebunden werden:

  • Fügen Sie den Modulnamen zu /etc/sysconfig/modules hinzu.

  • Verwenden Sie eine „install“ Anweisung in /etc/modules.conf. Damit wird modprobe angewiesen, beim Laden des einen Moduls auch ein anderes zu laden. Beispiel:

    install snd-pcm modprobe -i snd-pcm ; modprobe \
        snd-pcm-oss ; true
    

    Diese Zeile veranlasst das System, sowohl snd-pcm als auch snd-pcm-oss zu laden, sobald snd-pcm geladen wird.

7.4.5. Nützliche Dokumentation

Weitere hilfreiche Dokumentation finden Sie an den folgenden Stellen: