#!/bin/bash # # Pfade zu den benötigten Dateien PCIIDS=pci.db # PCI-ID-Liste von http://pciids.sourceforge.net/pci.db PCIMAP=/lib/modules/`uname -r`/modules.pcimap SYSTEMMAP=/boot/System.map # # Tabulator- und Newline-Zeichen als Variable, ist so leichter lesbar Tab=$'\t' Newline=$'\n' # # Wir benötigen Zugriff auf /proc/bus/pci, daher prüfen, ob es das Verzeichnis # überhaupt gibt if [ ! /sys/bus/pci -a ! -d /proc/bus/pci ]; then echo "/sys/bus/pci und /proc/bus/pci existieren nicht." exit 1 fi # # Die PCI-ID-Datenbank (http://pciids.sf.net/pci.db) einlesen if [ -r "$PCIIDS" ]; then PCIIDCMD="cat $PCIIDS" else PCIIDCMD="wget -q -O - http://pciids.sf.net/pci.db" fi # PCI-Modulliste (/lib/modules/[Kernel-Version]/modules.pcimap) und # Kernel-Symbolliste (/boot/System.map) prüfen if [ ! -r "$PCIMAP" -o ! -r "$SYSTEMMAP" ]; then echo "PCI-Modul-Liste oder System.map nicht gefunden." exit 1 fi # # PCI-ID-Liste zeilenweise einlesen IFS="${Newline}" for z in `eval ${PCIIDCMD}`; do # Die Spalten sind mit Tabs getrennt -- aufsplitten IFS="${Tab}" set -- $z # Das erste Zeichen unterscheidet Vendor- und Device-Einträge case "$1" in v) # Hersteller-Eintrag: Nur verifizierte Einträge erlauben ($4=0) if [ "$4" = "0" ]; then declare v${2}=$3 fi ;; d) # Device-Eintrag declare d${2}=$3 ;; esac done # # PCI-Modul-Liste zeilenweise einlesen IFS="${Newline}" for z in `cat $PCIMAP`; do # Die Spalten sind mit (mehreren) Leerzeichen getrennt IFS=" " set -- $z # Spalte 2 und 3 enthalten Vendor-/Device-ID, 6 die Class-ID if [ "$2" = "0xffffffff" -a "$3" = "0xffffffff" ]; then # generischer Treiber für bestimmte Geräteklassen id="c${6:4:4}" elif [ "$3" = "0xffffffff" ]; then # generischer Treiber für alle Geräte des Herstellers id="m${2:6}" else id="m${2:6}${3:6}" fi if [ -z "${!id}" ]; then # Spalte 1 den Namen des Moduls declare ${id}="$1" else declare ${id}="${!id}${Tab}${1}" fi done # # Liste der vom Kernel unterstützten Geräte zeilenweise einlesen IFS="${Newline}" for z in `cat $SYSTEMMAP`; do # Die Spalten sind mit Leerzeichen getrennt IFS="${Tab} " set -- $z # Symbole mit "__devicestr_" am Anfang der 3. Spalte herauslösen if [ "${3:0:12}" = "__devicestr_" ]; then # Der Device-String ist mit Unterstichen von der ID getrennt IFS="_" set -- $3 # Der 4. Parameter ist die kombinierte Vendor- und Device-ID declare k${4}=1 fi done IFS=",${Tab}${Newline}" # # /sys/bus/pci/devices/* respektive /proc/bus/pci/??/* nach Geräten scannen if [ -e /sys/bus/pci/devices ]; then PCIDevices=/sys/bus/pci/devices/* Method="sysfs" elif [ -e /proc/bus/pci ]; then PCIDevices=/proc/bus/pci/??/* Method="proc" fi # Geräte nacheinander bestimmen for device in $PCIDevices; do if [ "$Method" = "sysfs" ]; then read Vendor < ${device}/vendor Vendor=${Vendor:2:4} read Device < ${device}/device Device=${Device:2:4} read Class < ${device}/class Class=${Class:2:4} elif [ "$Method" = "proc" ]; then # Vendor- und Device-ID auslesen und nach Hex wandeln Vendor=`hexdump -s 0 -n 2 -e '1/2 "%04x"' $device` Device=`hexdump -s 2 -n 2 -e '1/2 "%04x"' $device` # Class-ID: Teilt die Hardware in verschiedene Gruppen, 0x0200 sind # zum Beispiel Netzwerkkarten. Nachzulesen bei # http://www.pcidatabase.com/pci_c_header.php # in der Struktur "PciClassCodeTable" Class=`hexdump -s 10 -n 2 -e '1/2 "%04x"' $device` fi # variable Variablennamen generieren v="v${Vendor}" # Variablenname des Herstellernamens d="d${Vendor}${Device}" # Variablenname der Gerätebeschreibung m="m${Vendor}${Device}" # Variablenname des Kernel-Moduls g="m${Vendor}" # Variablenname des generischen Kernel-Moduls k="k${Vendor}${Device}" # Variablenname des Kernel-Symbols c="c${Class}" # PCI-Geräteklasse echo "Hersteller: ${!v}${Tab}[0x${Vendor}]" echo "Gerät: ${!d}${Tab}[0x${Device}]" # echo "Klasse: [0x${Class}]" if [ -n "${!m}" -o -n "${!g}" -o -n "${!c}" ]; then set -- ${!m} ${!g} ${!c} if [ "$#" -gt "1" ]; then echo "Kernel-Module: $*" else echo "Kernel-Modul: $1" fi elif [ -n "${!k}" ]; then echo "Vom Kernel unterstützt" else echo "Nicht unterstützt" fi echo done