Wie finde ich den Treiber (Modul) für ein Gerät unter Linux?

48

Unter Linux gegeben:

  • ein Gerät, zum Beispiel /dev/sda,
  • und seine großen und kleinen Zahlen, zum Beispiel 8, 0,

wie kann ich wissen, welches Modul / welcher Treiber es "fährt"?

Kann ich mich damit befassen /sysoder /proces entdecken?

Totor
quelle
Eine Kombination aus lsmod, /proc/modulesund modinfo?
4
stackoverflow.com/questions/2911050 sieht genauso aus wie diese Frage.
Michael Tomkins
Totor, ich habe das Kopfgeld hinzugefügt, weil ein anderer Benutzer die gleiche Frage gestellt hat, weil er der Meinung war, dass dieser Benutzer nicht genügend Aufmerksamkeit erhalten hat. Ich bat ihn, seine Frage zu löschen und bot ihm ein Kopfgeld an, um mehr Antworten zu erhalten. Bitte denken Sie daran, eine der folgenden Antworten zu akzeptieren, wenn sie Ihre Frage beantworten.
Terdon
@terdon danke für das Kopfgeld, es hat nette Antworten hervorgebracht. Ich habe noch nicht alles sorgfältig getestet, werde aber in der Zwischenzeit Graemes Antwort akzeptieren .
Totor

Antworten:

56

Um diese Informationen sysfsfür eine Gerätedatei abzurufen, ermitteln Sie zuerst die Haupt- / Nebenzahl, indem Sie die Ausgabe von ls -lz

 $ ls -l /dev/sda
 brw-rw---- 1 root disk 8, 0 Apr 17 12:26 /dev/sda

Das 8, 0sagt uns, dass die Hauptzahl 8und die Nebenzahl ist 0. Der bam Anfang der Auflistung steht auch, dass es sich um ein Blockgerät handelt. Andere Geräte können cam Anfang ein For-Character-Gerät haben.

Wenn Sie dann unter nachsehen /sys/dev, sehen Sie, dass es zwei Verzeichnisse gibt. Einer hat angerufen blockund einer hat angerufen char. Hier ist es ein Kinderspiel, dass dies für Block- bzw. Zeichengeräte gilt. Jedes Gerät ist dann über seine Haupt- / Nebenstellennummer in diesem Verzeichnis erreichbar. Wenn für das Gerät ein Treiber verfügbar ist, können Sie diesen finden, indem Sie das Ziel des driverLinks in diesem oder dem deviceUnterverzeichnis lesen . Zum Beispiel kann /dev/sdaich für meine einfach tun:

$ readlink /sys/dev/block/8\:0/device/driver
../../../../../../../bus/scsi/drivers/sd

Dies zeigt, dass der sdTreiber für das Gerät verwendet wird. Wenn Sie sich nicht sicher sind, ob es sich bei dem Gerät um ein Block- oder Zeichengerät handelt, können Sie in der Shell diesen Teil einfach durch ein ersetzen *. Das funktioniert genauso gut:

$ readlink /sys/dev/*/8\:0/device/driver
../../../../../../../bus/scsi/drivers/sd

Auf Blockgeräte kann auch direkt über ihren Namen über /sys/blockoder zugegriffen werden /sys/class/block. Z.B:

$ readlink /sys/block/sda/device/driver
../../../../../../../bus/scsi/drivers/sd

Beachten Sie, dass sich das Vorhandensein verschiedener Verzeichnisse in /sysAbhängigkeit von der Kernelkonfiguration ändern kann. Auch haben nicht alle Geräte einen deviceUnterordner. Dies ist beispielsweise der Fall für Partitionsgerätedateien wie /dev/sda1. Hier muss auf das Gerät für die gesamte Festplatte zugegriffen werden (leider gibt es dafür keine sysLinks).

Als letztes kann es nützlich sein, die Treiber für alle Geräte aufzulisten, für die sie verfügbar sind. Dazu können Sie mit Hilfe von Globs alle Verzeichnisse auswählen, in denen die Treiberlinks vorhanden sind. Z.B:

$ ls -l /sys/dev/*/*/device/driver ls -l /sys/dev/*/*/driver 
ls: cannot access ls: No such file or directory
lrwxrwxrwx 1 root root 0 Apr 17 12:27 /sys/dev/block/11:0/device/driver -> ../../../../../../../bus/scsi/drivers/sr
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/block/8:0/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/block/8:16/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/block/8:32/device/driver -> ../../../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:0/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:1024/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:128/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:256/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:384/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/189:512/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/189:513/driver -> ../../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/189:514/driver -> ../../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/189:640/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/189:643/driver -> ../../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:768/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:896/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/21:0/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/21:1/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:27 /sys/dev/char/21:2/device/driver -> ../../../../../../../bus/scsi/drivers/sr
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/21:3/device/driver -> ../../../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/250:0/device/driver -> ../../../../../../../bus/hid/drivers/hid-generic
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/250:1/device/driver -> ../../../../../../../bus/hid/drivers/hid-generic
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/250:2/device/driver -> ../../../../../../../bus/hid/drivers/hid-generic
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/252:0/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/252:1/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:27 /sys/dev/char/252:2/device/driver -> ../../../../../../../bus/scsi/drivers/sr
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/252:3/device/driver -> ../../../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/254:0/device/driver -> ../../../bus/pnp/drivers/rtc_cmos
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/29:0/device/driver -> ../../../bus/platform/drivers/simple-framebuffer
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/4:64/device/driver -> ../../../bus/pnp/drivers/serial
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/4:65/device/driver -> ../../../bus/platform/drivers/serial8250
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/4:66/device/driver -> ../../../bus/platform/drivers/serial8250
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/4:67/device/driver -> ../../../bus/platform/drivers/serial8250
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/6:0/device/driver -> ../../../bus/pnp/drivers/parport_pc
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/99:0/device/driver -> ../../../bus/pnp/drivers/parport_pc

Um ein wenig von der Frage abzuweichen, füge ich einen weiteren /sysGlob-Trick hinzu, um einen viel umfassenderen Überblick darüber zu erhalten, welche Treiber von welchen Geräten verwendet werden (allerdings nicht unbedingt die mit einer Gerätedatei):

find /sys/bus/*/drivers/* -maxdepth 1 -lname '*devices*' -ls

Aktualisieren

Wenn Sie sich die Ausgabe von genauer ansehen udevadm, scheint dies zu funktionieren, indem Sie das kanonische /sysVerzeichnis suchen (wie Sie es erhalten würden, wenn Sie die Haupt- / Nebenverzeichnisse oben dereferenzieren würden), dann den Verzeichnisbaum nach oben durcharbeiten und alle gefundenen Informationen ausdrucken. Auf diese Weise erhalten Sie Informationen zu übergeordneten Geräten und den von ihnen verwendeten Treibern.

Um damit zu experimentieren, habe ich das folgende Skript geschrieben, um den Verzeichnisbaum zu durchlaufen und Informationen auf jeder relevanten Ebene anzuzeigen. udevscheint auf jeder Ebene nach lesbaren Dateien zu suchen, in die ihre Namen und Inhalte eingefügt werden ATTRS. Anstatt dies zu tun, zeige ich den Inhalt der ueventDateien auf jeder Ebene an (anscheinend definiert das Vorhandensein dieser Ebene eine andere als nur ein Unterverzeichnis). Ich zeige auch den Basisnamen aller gefundenen Subsystem-Links und dies zeigt, wie das Gerät in diese Hierarchie passt. udevadmzeigt nicht die gleichen Informationen an, daher ist dies ein nützliches ergänzendes Tool. Die übergeordneten Geräteinformationen (z. B. PCIInformationen) sind auch nützlich, wenn Sie die Ausgabe anderer Tools lshwan Geräte höherer Ebene anpassen möchten .

#!/bin/bash

dev=$(readlink -m $1)

# test for block/character device
if [ -b "$dev" ]; then
  mode=block
elif [ -c "$dev" ]; then
  mode=char
else
  echo "$dev is not a device file" >&2
  exit 1
fi

# stat outputs major/minor in hex, convert to decimal
data=( $(stat -c '%t %T' $dev) ) || exit 2
major=$(( 0x${data[0]} ))
minor=$(( 0x${data[1]} ))

echo -e "Given device:     $1"
echo -e "Canonical device: $dev"
echo -e "Major: $major"
echo -e "Minor: $minor\n"

# sometimes nodes have been created for devices that are not present
dir=$(readlink -f /sys/dev/$mode/$major\:$minor)
if ! [ -e "$dir" ]; then
  echo "No /sys entry for $dev" >&2
  exit 3
fi

# walk up the /sys hierarchy one directory at a time
# stop when there are three levels left 
while [[ $dir == /*/*/* ]]; do

  # it seems the directory is only of interest if there is a 'uevent' file
  if [ -e "$dir/uevent" ]; then
    echo "$dir:"
    echo "  Uevent:"
    sed 's/^/    /' "$dir/uevent"

    # check for subsystem link
    if [ -d "$dir/subsystem" ]; then
        subsystem=$(readlink -f "$dir/subsystem")
        echo -e "\n  Subsystem:\n    ${subsystem##*/}"
    fi

    echo
  fi

  # strip a subdirectory
  dir=${dir%/*}
done
Graeme
quelle
Gibt es eine Möglichkeit, alle verwendeten Treiber zu ermitteln? Wie zum Beispiel die udevadmAntwort wird Ihnen sdund geben ahci. Gibt es eine Möglichkeit, festzustellen, ahciob auch verwendet wird?
Patrick
@ Patrick, ja, aktualisiert.
Graeme
Tolle Antwort, danke! Nur zur Erinnerung, in meinem Fall war der Link in device/device/, also readlinksah mein Befehl so aus readlink /sys/dev/char/XX\:Y/device/device/driver.
Harry Cutts
19

Sie können das udevadmTool verwenden, um dies zu entdecken.
Der Befehl wäre udevadm info -a -n /dev/sda, und dann schauen Sie sich die DRIVER==Parameter an.

# udevadm info -a -n /dev/sda | grep -oP 'DRIVERS?=="\K[^"]+'  
sd
ahci

Dies zeigt, dass tatsächlich 2 Treiber an der Bereitstellung dieses Geräts beteiligt sind, sdund ahci. Der erste sdist direkt für das /dev/sdaGerät verantwortlich, nutzt aber den ahciTreiber underneith.

 

Die Ausgabe des udevadmBefehls sieht folgendermaßen aus und enthält eine Beschreibung der Funktionsweise.

# udevadm info -a -n /dev/sda      

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda':
    KERNEL=="sda"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{ro}=="0"
    ATTR{size}=="500118192"
    ATTR{stat}=="   84786     1420  3091333    40215   966488    12528 14804028  2357668        0  1146934  2396653"
    ATTR{range}=="16"
    ATTR{discard_alignment}=="0"
    ATTR{events}==""
    ATTR{ext_range}=="256"
    ATTR{events_poll_msecs}=="-1"
    ATTR{alignment_offset}=="0"
    ATTR{inflight}=="       0        0"
    ATTR{removable}=="0"
    ATTR{capability}=="50"
    ATTR{events_async}==""

  looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0':
    KERNELS=="0:0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS=="sd"
    ATTRS{rev}=="VZJ4"
    ATTRS{type}=="0"
    ATTRS{scsi_level}=="6"
    ATTRS{model}=="LITEONIT LMT-256"
    ATTRS{state}=="running"
    ATTRS{queue_type}=="simple"
    ATTRS{iodone_cnt}=="0x10daad"
    ATTRS{iorequest_cnt}=="0x10ead1"
    ATTRS{queue_ramp_up_period}=="120000"
    ATTRS{device_busy}=="0"
    ATTRS{evt_capacity_change_reported}=="0"
    ATTRS{timeout}=="30"
    ATTRS{evt_media_change}=="0"
    ATTRS{ioerr_cnt}=="0x2"
    ATTRS{queue_depth}=="31"
    ATTRS{vendor}=="ATA     "
    ATTRS{evt_soft_threshold_reached}=="0"
    ATTRS{device_blocked}=="0"
    ATTRS{evt_mode_parameter_change_reported}=="0"
    ATTRS{evt_lun_change_reported}=="0"
    ATTRS{evt_inquiry_change_reported}=="0"
    ATTRS{iocounterbits}=="32"
    ATTRS{eh_timeout}=="10"

  looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0':
    KERNELS=="target0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

  looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1/host0':
    KERNELS=="host0"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

  looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1':
    KERNELS=="ata1"
    SUBSYSTEMS==""
    DRIVERS==""

  looking at parent device '/devices/pci0000:00/0000:00:1f.2':
    KERNELS=="0000:00:1f.2"
    SUBSYSTEMS=="pci"
    DRIVERS=="ahci"
    ATTRS{irq}=="41"
    ATTRS{subsystem_vendor}=="0x144d"
    ATTRS{broken_parity_status}=="0"
    ATTRS{class}=="0x010601"
    ATTRS{enabled}=="1"
    ATTRS{consistent_dma_mask_bits}=="64"
    ATTRS{dma_mask_bits}=="64"
    ATTRS{local_cpus}=="0f"
    ATTRS{device}=="0x1e03"
    ATTRS{msi_bus}==""
    ATTRS{local_cpulist}=="0-3"
    ATTRS{vendor}=="0x8086"
    ATTRS{subsystem_device}=="0xc0d3"
    ATTRS{numa_node}=="-1"
    ATTRS{d3cold_allowed}=="1"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""
Patrick
quelle
1
@ECarterYoung Wo sehen Sie, dass udevadmentfernt (oder sogar empfohlen) wird? Ich kann nichts finden, was einen Hinweis darauf gibt.
Patrick
1
@ECarterYoung ich habe, sehe ich nichts dergleichen.
Patrick
Ich habe mich in Bezug auf das Fehlen von UEVENT_HELPER im Kernel geirrt. Auf Systemen, auf denen systemd ausgeführt wird, ist dieser Eintrag leer, der Helpr ist jedoch weiterhin auf dem System vorhanden.
Eyoung100
4

Verwenden Sie den Befehl hwinfo und geben Sie das Modell und den Treiber aus. Wenn kein Treiber vorhanden ist, wird dieser nicht angezeigt. Zum Beispiel für Festplatten:

# hwinfo --block | grep -Ei "Treiber \: | Modell \:"
  Modell: "Diskette"
  Modell: "FUJITSU MHZ2080B"
  Treiber: "ahci", "sd"
  Modell: "Partition"
  Modell: "Partition"
  Modell: "Partition"
  Modell: "Generic Multi-Card"
  Treiber: "ums-realtek", "sd"
  Modell: "Realtek USB2.0-CRW"
  Treiber: "ums-realtek"

Für Netzwerkkarten:

# hwinfo --netcard | grep -Ei "Treiber \: | Modell \:"
  Modell: "Broadcom NetXtreme BCM5764M Gigabit Ethernet PCIe"
  Treiber: "tg3"
  Modell: "Intel Wireless WiFi Link 5100"
  Treiber: "iwlwifi"

Für USB-Geräte:

# hwinfo --usb | grep -Ei "Treiber \: | Modell \:"
  Modell: "Linux 3.11.10-7-desktop uhci_hcd UHCI Host Controller"
  Treiber: "hub"
  Modell: "Linux 3.11.10-7-desktop uhci_hcd UHCI Host Controller"
  Treiber: "hub"
  Modell: "IDEACOM IDC 6680"
  Fahrer: "usbhid"
  [...]

Verwenden Sie hwinfo --help, um herauszufinden, welche anderen Gerätetypen Sie abfragen können. hwinfo wird standardmäßig installiert, z. B. unter SUSE Linux.

Thorsten Staerk
quelle
Um dies auf eine bestimmte Gerätedatei zu beziehen, können Sie die --onlyOption hinzufügen . Eg hwinfo --block --only /dev/sda | grep ....
Graeme
3

lshwist ein großartiges Tool, um die in Ihrem Computer gefundene Hardware aufzulisten. Sie müssen es zuerst installieren, bevor Sie es ausführen können.

$ yum install lshw
$ apt-get install lshw

Verwenden Sie yumoder apt-getje nach verwendetem System. Gehen Sie dann wie folgt vor, um die Speicherhardware speziell aufzulisten:

# lshw -class storage 
*-storage               
   description: SATA controller
   product: 5 Series/3400 Series Chipset 4 port SATA AHCI Controller
   vendor: Intel Corporation
   physical id: 1f.2
   bus info: pci@0000:00:1f.2
   version: 06
   width: 32 bits
   clock: 66MHz
   capabilities: storage msi pm ahci_1.0 bus_master cap_list
   configuration: driver=ahci latency=0
   resources: irq:41 ioport:1830(size=8) ioport:1824(size=4) ioport:1828(size=8) ioport:1820(size=4) ioport:1800(size=32) memory:f0305000-f03057ff

Möglicherweise möchten Sie es ausführen root, um alle Informationen zurückzugewinnen.

Ansonsten lspcikann man auch Angaben zu deiner Hardware machen:

$ lspci -vv
00:1f.2 SATA controller: Intel Corporation 5 Series/3400 Series Chipset 4 port SATA AHCI Controller (rev 06) (prog-if 01 [AHCI 1.0])
    Subsystem: Dell Device 0434
    Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
    Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
    Latency: 0
    Interrupt: pin B routed to IRQ 41
    Region 0: I/O ports at 1830 [size=8]
    Region 1: I/O ports at 1824 [size=4]
    Region 2: I/O ports at 1828 [size=8]
    Region 3: I/O ports at 1820 [size=4]
    Region 4: I/O ports at 1800 [size=32]
    Region 5: Memory at f0305000 (32-bit, non-prefetchable) [size=2K]
    Capabilities: <access denied>
    Kernel driver in use: ahci

Um die Haupt- und Nebennummer eines Geräts herauszufinden, führen Sie lses einfach aus .

$ ls -l /dev/sda
brw-rw----. 1 root disk 8, 0 13 avril 10:54 /dev/sda

In dieser Ausgabe bedeutet bin brw-rw----., dass es sich um ein Blockgerät handelt. Die Ziffern 8und 0sind jeweils die Haupt- und Nebennummer des Geräts.

Spack
quelle
1
Meine Frage ist es, die Verbindung zwischen einem Gerät und seinem Modul / Treiber zu finden. Wo antwortest du das?
Totor
1
@Totor In beiden Ausgaben von lshwund sehen lspciSie das von einem Gerät verwendete Modul: configuration: driver = ahci latence = 0 und den verwendeten Kerneltreiber: ahci .
Spack