Unter Linux gegeben:
- ein Gerät, zum Beispiel
/dev/sda
, - und seine Major- und Minor-Nummern, zum Beispiel
8, 0
,
woher weiß ich, welches Modul/Treiber es „antreibt“?
Kann ich in /sys
graben oder /proc
um das zu entdecken?
Akzeptierte Antwort:
Um diese Informationen von sysfs
zu erhalten Bestimmen Sie für eine Gerätedatei zuerst die Major/Minor-Nummer, indem Sie sich die Ausgabe von ls -l
ansehen , zB
$ ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 Apr 17 12:26 /dev/sda
Die 8, 0
sagt uns, dass die Hauptnummer 8
ist und der Minor ist . Das
b
am Anfang der Auflistung sagt uns auch, dass es sich um ein Blockgerät handelt. Andere Geräte haben möglicherweise ein c
für Zeichengerät am Anfang.
Schaut man dann unter /sys/dev
nach , sehen Sie, dass es zwei Verzeichnisse gibt. Einer namens block
und eine namens char
. Das Kinderspiel hier ist, dass diese jeweils für Block- und Zeichengeräte sind. Jedes Gerät ist dann über seine Major/Minor-Nummer in diesem Verzeichnis erreichbar. Wenn für das Gerät ein Treiber verfügbar ist, kann dieser gefunden werden, indem das Ziel des driver
gelesen wird Link in diesem oder dem device
Unterverzeichnis. ZB für mein /dev/sda
Ich kann einfach Folgendes tun:
$ readlink /sys/dev/block/8\:0/device/driver
../../../../../../../bus/scsi/drivers/sd
Dies zeigt, dass die sd
Treiber 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 diesen Teil in der Shell 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/block
zugegriffen werden oder /sys/class/block
. Beispiel:
$ readlink /sys/block/sda/device/driver
../../../../../../../bus/scsi/drivers/sd
Beachten Sie, dass das Vorhandensein verschiedener Verzeichnisse in /sys
kann sich je nach Kernel-Konfiguration ändern. Auch haben nicht alle Geräte ein device
Unterordner. Dies ist beispielsweise bei Partitionsgerätedateien wie /dev/sda1
der Fall . Hier müssen Sie auf das Gerät für die gesamte Festplatte zugreifen (leider gibt es keine sys
Links dazu).
Eine letzte Sache, die nützlich sein kann, ist, die Treiber für alle Geräte aufzulisten, für die sie verfügbar sind. Dazu können Sie mit Globs alle Verzeichnisse auswählen, in denen die Treiberverknüpfungen vorhanden sind. Beispiel:
$ ls -l /sys/dev/*/*/device/driver && ls -l /sys/dev/*/*/driver
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
Abschließend, um ein wenig von der Frage abzuweichen, füge ich ein weiteres /sys
hinzu glob-Trick, um einen viel breiteren Überblick darüber zu erhalten, welche Treiber von welchen Geräten verwendet werden (wenn auch nicht unbedingt von denen mit einer Gerätedatei):
find /sys/bus/*/drivers/* -maxdepth 1 -lname '*devices*' -ls
Aktualisieren
Schauen Sie sich die Ausgabe von udevadm
genauer an , scheint es zu funktionieren, indem es den kanonischen /sys
findet Verzeichnis (wie Sie es erhalten würden, wenn Sie die Haupt-/Nebenverzeichnisse oben dereferenzieren würden), arbeitet sich dann den Verzeichnisbaum nach oben und druckt alle gefundenen Informationen aus. Auf diese Weise erhalten Sie auch Informationen über übergeordnete Geräte und alle von ihnen verwendeten Treiber.
Um damit zu experimentieren, habe ich das folgende Skript geschrieben, um den Verzeichnisbaum nach oben zu gehen und Informationen auf jeder relevanten Ebene anzuzeigen. udev
scheint auf jeder Ebene nach lesbaren Dateien zu suchen, deren Namen und Inhalte in ATTRS
aufgenommen werden . Stattdessen zeige ich den Inhalt des uevent
an Dateien auf jeder Ebene (anscheinend definiert das Vorhandensein dieser eine bestimmte Ebene und nicht nur ein Unterverzeichnis). Ich zeige auch den Basisnamen aller Subsystem-Links, die ich finde, und dies zeigt, wie das Gerät in diese Hierarchie passt. udevadm
zeigt nicht die gleichen Informationen an, daher ist dies ein nettes ergänzendes Tool. Die übergeordneten Geräteinformationen (z. B. PCI
information) ist auch nützlich, wenn Sie die Ausgabe anderer Tools wie lshw
abgleichen möchten zu Geräten höherer Ebene.
#!/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