# 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

- lspci(8)
- `usb-uhci.o`
- `usb-ohci.o`
- `/etc/usbmgr/`
- usbmodules
- `/etc/hotplug`

### 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:

- Intel
- VIA (auch VIA basierte USB-Adapter)

Mainboards der folgenden Firmen benutzen OHCI:

- Compaq
- Ali
- SiS
- NEC
- Opti Chipsatz

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

- usb-ohci.o
- usb-uhci.o

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:

- hotplug
  Ein Programm, das die Hotplugging-Fähigkeit für viele verschiedene Systeme anbietet, etwa USB oder PCMCIA.
- usbmgr
  Ein Programm, das die Hotplugging-Fähigkeit nur für USB anbietet.

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:

- `/etc/usbmgr/usbmgr.conf`
  Eine Datei, die die offiziellen IDs enthält. Diese Datei kann aktuell über http://www.wondernetworkresources.com/staff/shuu/linux/usbmgr/ bezogen werden und muß nicht verändert werden. Sie dient nur der Information, welche Module für welche IDs geladen werden müssen.
- `/etc/usbmgr/preload.conf`
  Diese Datei enthält eine Liste der Module, die usbmgr laden soll, wenn er startet. Diese Datei kann vom Systemverwalter entsprechend verändert werden.
- `/etc/usbmgr/host`
  enthält den Modulnamen (ohne `.o`) des verwendeten USB-Hostcontrollers also entweder `usb-ohci` oder `usb-uhci`

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

- Der Kernel muß USB-fähig sein (usbcore)
- Das USBDEVFS muß unterstützt werden
- Die benötigten Kernelmodule müssen existieren

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