Zurück

1.101.7

Konfiguration von USB-Geräten


Beschreibung: Prüfungskandidaten sollten in der Lage sein, USB-Unterstützung zu aktivieren und verschiedene USB-Geräte zu verwenden und zu konfigurieren. Dieses Lernziel beinhaltet die korrekte Auswahl des USB-Chipsatzes und des dazugehörigen Moduls. Ebenfalls enthalten ist das Wissen über die allgemeine Architektur des USB-Schichtenmodells und die verschiedenen Module, die in den einzelnen Schichten verwendet werden.

Die wichtigsten Dateien, Bezeichnungen und Anwendungen


Grundsätzliche Unterstützung von USB

USB wird von Kerneln ab Version 2.2.7 unterstützt. Besser sind die Kernel ab 2.4.0. Die generelle Unterstützung von USB ist heute meist fest in einen Kernel hineingebaut, kann aber auch als Modul realisiert werden. Dieses Modul muß - falls mit USB gearbeitet werden soll - entsprechend geladen werden. Das Modul heißt usbcore.o und kann mit dem Befehl
  modprobe usbcore
im laufenden Betrieb eingehängt werden. Üblich ist aber, daß diese grundsätzliche USB-Unterstützung fest integriert ist. Beim Booten sollte - falls das der Fall ist - eine Meldung wie die folgende angezeigt werden:
  usb.c: registered new driver usbdevfs
  usb.c: registered new driver hub
  Initializing USB Mass Storage driver...
  usb.c: registered new driver usb-storage
  USB Mass Storage support registered.
Damit ist klar, daß die USB-Unterstützung grundsätzlich aktiviert ist.

UHCI oder OHCI

Die meisten modernen Mainboards stellen einen USB-Controller zur Verfügung. Ältere Maschinen können mit einem USB-Controller auf einer PCI-Karte nachgerüstet werden. USB-Controler sind entweder kompatibel zum Open Host Controller Interface (OHCI - Compaq) oder zum Universal Host Controller Interface (UHCI - Intel). Beide Typen haben die selben Fähigkeiten und USB-Geräte arbeiten mit beiden Typen zusammen.

Die wesentliche Aufgabe bei der Konfiguration von USB unter Linux ist es, herauszufinden, welchen der beiden Controller auf dem Rechner verwendet wird, auf dem USB konfiguriert werden soll.

Mainboards der folgenden Firmen benutzen UHCI:

Mainboards der folgenden Firmen benutzen OHCI:

Eine gute Methode, um den entsprechenden Chipsatz herauszufinden ist ein Aufruf von lspci. Eine typische Ausgabe wäre z.B.

  ...
  00:07.1 IDE interface: VIA Technologies, Inc. Bus Master IDE (rev 06)
  00:07.2 USB Controller: VIA Technologies, Inc. USB (rev 16)
  00:07.3 USB Controller: VIA Technologies, Inc. USB (rev 16)
  00:07.4 Bridge: VIA Technologies, Inc. VT82C686 [Apollo Super ACPI] (rev 40)
  ...
was eindeutig VIA - also UHCI bedeutet.

Falls das nicht weiterführt, gibt es die Möglichkeit, die Datei /proc/pci anzusehen. Dort findet sich ein Eintrag in der Art:

  Bus  0, device   7, function  3:
    USB Controller: VIA Technologies, Inc. UHCI USB (#2) (rev 22).
      IRQ 10.
      Master Capable.  Latency=32.  
      I/O at 0xa800 [0xa81f].
Wenn auch hier keine Angaben stehen, dann sollte die IO-Adresse angesehen werden. Ist sie in der Form 0xHHHH (wobei HHHH für vier hexadezimale Ziffern steht), dann haben wir es mit UHCI zu tun, ansonsten, wenn die Form der Adresse 0xHH000000 ist, dann ist es OHCI.

Sobald herausgefunden wurde, welcher Controller benutzt wird, kann das Grundmodul für USB geladen werden. Das ist eines der beiden folgenden Module

Geladen werden diese Module entweder von Hand über den Befehl

  modprobe usb-uhci
oder
  modprobe usb-ohci
oder automatisiert über einen entsprechenden Eintrag in /etc/modules.conf etwa in der Art:
  alias usb uhci
Jetzt kann in einer Systemstartdatei ein modprobe usb eingetragen werden und das entsprechende Modul wird automatisch beim Start geladen. Es ist sogar möglich dadurch alle gewünschten anderen USB-Module gleich mitzuladen, etwa indem dort eingetragen wird
  alias usb uhci
  post-install uhci modprobe printer
  post-install printer modprobe joydev
  post-install joydev modprobe hid 

Das USBDevFS-Dateisystem

Das USB Geräte-Dateisystem ist ein dynamisch generiertes Dateisystem, ähnlich dem /proc Dateisystem. Es kann theoretisch an jede beliebige Stelle des Systems gemountet werden, es hat sich aber durchgesetzt, es nach /proc/bus/usb einzuhängen.

Wenn im Kernel die Unterstützung für dieses Dateisystem aktiviert ist (Preliminary USB Device Filesystem) dann sollte es - bei 2.4er Kerneln automatisch beim Start gemountet werden. Ältere Kernel erfordern entweder Handarbeit wie

  mount -t usbdevfs none /proc/bus/usb
oder einen Eintrag nach /etc/fstab in der Art
  none    /proc/bus/usb       usbdevfs   defaults   0   0
Nachdem das Dateisystem gemountet ist, sollte der Inhalt von /proc/bus/usb etwa folgendermaßen aussehen:
  -r--r--r--    1 root     root            0 2002-08-20 00:02 devices
  -r--r--r--    1 root     root            0 2002-08-20 00:02 drivers
Sobald das entsprechende Modul usb-ohci.o oder usb-uhci.o geladen ist, der USB-Controller also ansprechbar ist, sollte mindestens noch ein (meist aber zwei) Unterverzeichnis zu finden sein, für jede USB-Schnittstelle eines:
  dr-xr-xr-x    1 root     root            0 2002-08-20 00:11 001
  dr-xr-xr-x    1 root     root            0 2002-08-20 00:11 002
  -r--r--r--    1 root     root            0 2002-08-20 00:11 devices
  -r--r--r--    1 root     root            0 2002-08-20 00:11 drivers
Die Einträge in diesen Verzeichnissen und Dateien sind binär und somit nicht für menschliche Augen gedacht. Es geht darum, im Fehlerfall Zugriff auf jedes einzelne Gerät zu haben und Diagnosen stellen zu können.

Das USB-Schichtenmodell von Linux

Um zu verstehen, welche Module wie voneinander abhängen, folgt hier eine Darstellung des USB-Schichtenmodells, wie es der Linux-Kernel benutzt. Daraus wird klar, daß der USB-Kern (usbcore) nicht die unterste Schicht des USB-Stapels ist, sondern in beide Richtungen erweiterbar ist.

Nach "unten" hin, also Richtung Controller-Hardware sind ihm die bereits besprochenen USB-Hostcontroller-Module (usb-ohci und usb-uhci) angeschlossen, mit denen er in die Lage versetzt wird, den entsprechenden USB-Controller anzusprechen. Nach "oben" hin folgen die Module, die für die einzelnen Geräte selbst notwendig sind.

Der Kern (usbcore) selbst stellt die Funktionalität von USB selbst zur Verfügung, also alles, was für alle Geräte gleich ist.

Die einzelnen Geräte, die über USB angeschlossen werden, können in sogenannte Klassen aufgeteilt werden. Als Klassen werden Geräte zusammengefasst, die eine bestimmte Menge gleichartiger Mechanismen benutzen. Unter Linux ist die Aufteilung nicht besonders intensiv, die einzige große Klasse, die sich ergibt ist die Klasse HID. (Human Interface Device - Gerät für eine menschliche Schnittstelle). Diese Klasse fasst alles zusammen, was als Eingabegerät des Benutzers klassifiziert werden kann. Also z.B. Tastatur, Mouse und Joystick. Das entsprechende Modul unter Linux heißt hid.o.

Diese Klasse wiederum benutzt ein weiteres Modul, das die Eingabe (input) von solchen Geräten regelt. Unter Linux wird diese Aufgabe vom Modul input.o gelöst. Erst darauf bauen dann die einzelnen Module für die jeweiligen Eingabegeräte wie etwa usbkbd.o oder usbmouse.o auf.

Durch diese Architektur ist es relativ wenig Aufwand, neue Treiber für Eingabegeräte zu schreiben. Die wesentliche Funktionalität ist ja schon durch die Module hid.o und input.o gegeben. Nur noch die spezifischen Besonderheiten des jeweiligen Gerätes müssen in den entsprechenden Treiber integriert werden.

Andere Geräte, die nicht zur HID-Klasse gehören, verwenden nur jeweils ein Modul, um die entsprechende Funktionalität zur Verfügung zu stellen. So wird z.B. für den Einsatz eines USB-Druckers nur das Modul printer.o benötigt. Dieses Modul erstellt dann eine (oder mehrere) Gerätedatei(en) im Verzeichnis /dev/usb, die wie parallele Schnittstellen zu benutzen sind (/dev/usb/lp0), um einen dort angeschlossenen Drucker entsprechend anzusprechen.

Wenn also an USB kein Eingabegerät angehängt ist, so kann auf den Einsatz des gesamten HID/Input Astes verzichtet werden.

Genauere Informationen, über die gefundenen (angeschlossenen) USB-Geräte sind mit dem Programm lsusb zu ermitteln.

Module für die USB-Geräte automatisch einbinden

USB ist von seinem ganzen Ansatz her ein sogenannter Hotplugging Service, also ein Dienst, der im laufenden Betrieb ein- und ausgehängt werden kann. Diese Fähigkeit wird von Linux unterstützt, es müssen dazu aber ein paar Voraussetzungen erfüllt sein.

Grundsätzlich existieren zwei unterschiedliche Ansätze, um diese Fähigkeit anzubieten:

Beide Ansätze werden hier kurz beschrieben:

Funktionsweise von hotplug

hotplug ist ein Programm, das vom Kernel benutzt werden kann, um User-Programme von bestimmten Ereignissen (zumeist Hardware-spezifisch) zu unterrichten. Ein solches Ereignis kann beispielsweise das Anstecken eines USB- oder PCMCIA Gerätes sein. Das kann brauchbar sein, um die entsprechenden Module für dieses Gerät automatisch zu laden.

hotplug benutzt für jedes zu überwachende System einen sogenannten Agenten, ein Shellscript, normalerweise unter /etc/hotplug/Systemname.agent. Für USB wäre das also das Script /etc/hotplug/usb.agent.

Informationen über solche Ereignisse werden den Agenten vom Kernel über Umgebungsvariablen übermittelt. Das Programm usbmodules wird beispielsweise vom usb-Agenten benutzt, um die erkannten Geräte mit den notwendigen Modulen auszustatten. Die Information über die Geräte erhält hotplug über die Umgebungsvariable DEVICES.

hotplug ist ein Daemon, der über ein init-Script (/etc/init.d/hotplug) gestartet wird.

Funktionsweise von usbmgr

usbmgr ist ein Daemon, der benötigte USB-Module etsprechend seiner Konfigurationsdateien läd und entläd. Zusätzlich können noch Scripts ausgeführt werden, sofern das notwendig sein sollte. usbmgr benutzt die offiziellen USB-Vendor-IDs und die USB-Device-IDs, die vom USB-Consortium offiziell vergeben werden, um herauszufinden, welche Geräte er gefunden hat. Die beiden Konfigurationsdateien des Programms sind:

Für eine korrekte Funktion von usbmgr müssen folgende Voraussetzungen erfüllt sein:

Auch usbmgr ist ein Daemon, der über ein init-Script gestartet wird.