Open Source im professionellen Einsatz
Linux-Magazin 09/2005

Hardware-Erkennung für PCI und USB mit der Bash

Erkennungsdienst

Wer in die Verlegenheit kommt, ein Rettungssystem zu brauchen, vermisst schnell die Annehmlichkeiten einer automatischen Hardware-Erkennung. Die beiden exklusiv in diesem Artikel vorgestellten universellen Skripte scannen angeschlossene Geräte und listen übersichtlich die passenden Kernelmodule auf.

737

Die große Vielfalt der heute eingesetzten Hardware erfordert eine kaum übersichtlichere Anzahl an Treibern und Modulen im Linux-Kernel. Funktioniert die automatische Hardware-Erkennung einmal nicht wie gewohnt, etwa weil die installierte Distribution nicht mehr startet oder eine neu eingebaute Komponente nicht automatisch erkennt, muss der Administrator selbst nach den passenden Kernelmodulen suchen.

Prinzipiell stellen der Kernel und die Modullisten alle nötigen Informationen bereit, um den zum jeweiligen Gerät gehörigen Treiber zu finden ­ angesichts generischer Treiber für ganze Geräteklassen kann die Suche allerdings sehr kompliziert sein.

Die Skripte »pcidetect« für PCI und »usb-detect« für USB von [1] erleichtern den Umgang mit Rettungssystemen, Mini-Distributionen, Rescue-CDs und Embedded-Linux-Installationen, indem sie auflisten, welche Treiber direkt im Kernel einkompiliert sind, welche Module eventuell nachzuladen sind und welche Hardware vom aktuell laufenden Kernel gar nicht unterstützt wird.

Kernel-Interfaces

Die Hardware-Erkennung für PCI, USB und Firewire ist mit ein wenig Hintergrundwissen keine Hexerei und lässt sich mit nahezu jeder beliebigen Programmiersprache realisieren ­ der Autor wählte die Bash für die beiden Beispiel-Skripte von [1]. Alle nötigen Informationen zur Hardware wie Hersteller, Gerät und Geräteklasse stellt der Kernel per SysFS oder Proc zur Verfügung.

Am einfachsten funktioniert die Hardware-Erkennung mit SysFS, da hier anders als beim Proc-Interface keine Binärdaten zu verarbeiten sind.

Bei Sysfs gibt es für jedes PCI-Gerät unterhalb von »/sys/bus/pci/devices« einen symbolischen Link mit der jeweiligen PCI-ID, der auf das entsprechende Geräteverzeichnis unterhalb von »/sys/devices/pci*« zeigt. Der Zugriff über »/sys/bus/pci/devices« gestaltet sich einfacher, weil hier alle PCI-Geräte aller PCI-Busse zusammengefasst sind, während es unterhalb von »/sys/devices« für jeden PCI-Bus ein separates Verzeichnis mit den Geräten gibt.

Das Geräteverzeichnis enthält alle für die Hardware-Erkennung nötigen Daten: »vendor« verrät die Vendor-ID des Geräteherstellers in Hexadezimal-Schreibweise, »device« die Product-ID und »class« die Geräteklasse nach [3]. Die Zeilen 11 bis 16 von Listing 1 lesen die für die Hardwarebestimmung nötigen Daten aus der SysFS-Struktur ein.

Unterhalb von »/proc/bus/pci« sind die Pseudodateien der Geräte nach PCI-Controllern sortiert aufgelistet. Jede Gerätedatei enthält alle Angaben in konzen-trierter Form, die SysFS einzeln bereitstellt. Die Zeilen 18 bis 20 in Listing 1 zeigen den Abschnitt aus dem PCI-Hardware-Erkennungsskript »pcidetect« von [1], der Vendor- und Product-ID sowie den Class Code ermittelt. Eine komplette Beschreibung der Pseudodatei liefert der Artikel aus [4].

PCI-ID-Datenbank

Für die Klartextausgabe von Hersteller und Namen der PCI-Geräte benötigt das Hardware-Erkennungsskript die PCI-ID-Datenbank von [2], die auch der Linux-Kernel und »lspci« verwenden. Die PCI-Datenbank lässt sich sehr einfach parsen, Listing 2 zeigt den entsprechenden Abschnitt aus »pcidetect«. Die Variable »PCIIDCMD« enthält den Befehl zum Ein-lesen der PCI-ID-Datenbank, entweder ein einfaches »cat« der Datei oder einen entsprechenden »wget«-Aufruf.

In der Datei »pci.db« besteht jeder Hersteller- oder Geräte-Eintrag aus einer Zeile, in der die einzelnen Felder per Tabulator getrennt sind. Um jeweils eine komplette Zeile abzuarbeiten, setzt Zeile 1 von Listing 2 die Trennzeichen-Variable »IFS« auf den Zeilenumbruch. Um die Zeilen der Datenbank in ihre Felder aufzuspalten, schreibt Zeile 3 des Listings ein Tabulatorzeichen in die Variable »IFS«. Der »set«-Aufruf in Zeile 4 übernimmt dann die Trennung.

Die Abfrage in Zeile 8, ob die vierte Spalte eine »0« enthält, dient der Qualitätssicherung: Die PCI-Datenbank kann von jedermann erweitert werden, solche neuen Einträge werden mit einer »1« in Spalte 4 gekennzeichnet. Verifizierte Einträge bekommen dann eine »0«. Die Vendor-ID bei Herstellereinträgen und die kombinierte Vendor- und Device-ID bei Geräte-Einträgen sowie die Beschreibung speichern die Zeilen 9 und 13.

Listing 1: PCI-IDs
bestimmen

01 if [ -e /sys/bus/pci/devices ]; then
02   PCIDevices=/sys/bus/pci/devices/*
03   Method="sysfs"
04 elif [ -e /proc/bus/pci ]; then
05   PCIDevices=/proc/bus/pci/??/*
06   Method="proc"
07 fi
08 
09 for device in $PCIDevices; do
10   if [ "$Method" = "sysfs" ]; then
11     read Vendor < ${device}/vendor
12     Vendor=${Vendor:2:4}
13     read Device < ${device}/device
14     Device=${Device:2:4}
15     read Class < ${device}/class
16     Class=${Class:2:4}
17   elif [ "$Method" = "proc" ]; then
18     Vendor=`hexdump -s 0 -n 2 -e '1/2 "%04x"' $device`
19     Device=`hexdump -s 2 -n 2 -e '1/2 "%04x"' $device`
20     Class=`hexdump -s 10 -n 2 -e '1/2 "%04x"' $device`
21   fi

Listing 2: PCI-ID-Datenbank
einlesen

01 IFS="${Newline}"
02 for z in `eval ${PCIIDCMD}`; do
03   IFS="${Tab}"
04   set -- $z
05 
06   case "$1" in
07     v)
08       if [ "$4" = "0" ]; then
09         declare v${2}=$3
10       fi
11       ;;
12     d)
13       declare d${2}=$3
14       ;;
15   esac
16 done

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Knoten knüpfen

    Statische Gerätedateien sind angesichts aktueller Hardware nicht mehr zeitgemäß. So erfordert Hotplugging an USB- und anderen Bussen dynamisches Gerätehandling. DevFS erfüllt zwar viele Ansprüche an eine solche Lösung, wird aber nun von Udev abgelöst.

  • Universelle USB-MTP-Blacklist für Linux?

    Das Media Transfer Protokoll verursacht so manches Problem im Umgang mit USB-Geräten, unter Windows und Linux. Weil die Microsoft-Welt eine recht eigenwillige Lösung dafür gefunden hat, überlegen Entwickler wie Greg Kroah-Hartman auf der USB-Mailing-Liste, ob eine universelle USB-MTP-Blacklist geeignet wäre, das Problem auf Linux zu lösen.

  • Backup über Bande

    Wer Hotplug verstanden hat und ein Tool wie Ivman richtig zu nutzen versteht, dem öffnen sich die Türen zur Automatisierung beinahe beliebiger Abläufe. In diesem Artikel stößt ein Notebook Backups an, sobald sein Besitzer eine bestimmte Platte anstöpselt.

  • Kern-Technik

    USB hat die klassische serielle Schnittstelle als Allround-Interface abgelöst und macht mit Version 2.0 den Highspeed-Bussen Konkurrenz. Kernel 2.6 unterstützt schon ein breites Spektrum an Hardware und hilft unbekannte USB-Geräte direkt zu programmieren.

  • Die Netzstarter

    Plattenlose Clients auf Basis von Linux bieten die Möglichkeiten vollwertiger klassischer Workstations bei reduzierten Hardwarekosten, geringerem Lärmpegel sowie vermindertem Administrationsaufwand. Bei Standard-PC-Komponenten sinken die Kosten weiter.

comments powered by Disqus

Ausgabe 05/2017

Digitale Ausgabe: Preis € 7,62
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.