Linux

如何在 Linux 上找到與設備關聯的驅動程序(模組)?

  • August 3, 2020

在 Linux 上,給定:

  • 一個設備,例如/dev/sda
  • 及其主要和次要數字,例如8, 0

我怎樣才能知道哪個模組/驅動程序正在“驅動”它?

我可以深入研究/sys/proc發現嗎?

要從sysfs設備文件中獲取此資訊,首先通過查看的輸出確定主要/次要編號ls -l,例如

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

8, 0告訴我們主要數字是,8次要數字是0b清單開頭的 也告訴我們它是一個塊設備。其他設備可能c在開始時有一個字元設備。

如果你再看下/sys/dev,你會看到有兩個目錄。一呼block一呼char。這裡不費吹灰之力的是,它們分別用於塊設備和字元設備。然後每個設備都可以通過其主要/次要編號訪問此目錄。如果設備有可用的驅動程序,則可以通過讀取此目錄或子目錄中的driver連結目標來找到。device例如,對於我來說,/dev/sda我可以簡單地做:

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

這表明sd驅動程序用於設備。如果您不確定該設備是塊設備還是字元設備,在 shell 中您可以簡單地將這部分替換為*. 這同樣有效:

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

塊設備也可以通過它們的名稱通過/sys/block或直接訪問/sys/class/block。例如:

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

請注意,各種目錄的存在/sys可能會根據核心配置而改變。此外,並非所有設備都有device子文件夾。例如,分區設備文件就是這種情況,例如/dev/sda1. 在這裡,您必須訪問整個磁碟的設備(不幸的是,沒有sys此連結)。

最後一件有用的事情是列出所有可用設備的驅動程序。為此,您可以使用 glob 選擇存在驅動程序連結的所有目錄。例如:

$ 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

最後,為了稍微偏離這個問題,我將添加另一個/sysglob 技巧,以更廣泛地了解哪些設備正在使用哪些驅動程序(儘管不一定是那些具有設備文件的驅動程序):

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

更新

更仔細地查看 的輸出udevadm,它似乎可以通過查找規範/sys目錄(如果您取消引用上面的主要/次要目錄,您會得到),然後沿著目錄樹向上工作,列印出它找到的任何資訊。通過這種方式,您可以獲得有關父設備以及它們使用的任何驅動程序的資訊。

為了對此進行試驗,我編寫了下面的腳本來遍歷目錄樹並在每個相關級別顯示資訊。udev似乎在每個級別尋找可讀文件,它們的名稱和內容被合併到ATTRS. 我沒有這樣做,而是uevent在每個級別顯示文件的內容(似乎它的存在定義了一個不同的級別,而不僅僅是一個子目錄)。我還顯示了我找到的任何子系統連結的基本名稱,這顯示了設備如何適應此層次結構。udevadm不顯示相同的資訊,所以這是一個很好的補充工具。PCI如果您想將其他工具的輸出與lshw更高級別的設備相匹配,父設備資訊(例如資訊)也很有用。

#!/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

引用自:https://unix.stackexchange.com/questions/97676