Linux上のデバイスに関連付けられたドライバー(モジュール)を見つける方法


48

Linuxの場合:

  • たとえば/dev/sda、デバイス
  • およびそのメジャー番号とマイナー番号、たとえば8, 0

どのモジュール/ドライバーがそれを「駆動」しているかを知るにはどうすればよいですか?

それを掘り下げ/sysたり/proc、発見したりできますか?


いくつかの組み合わせlsmod/proc/modulesmodinfo

4
stackoverflow.com/questions/2911050はこの質問と同じように見えます。
マイケルトムキンズ14


Totor、賞金を追加したのは、別のユーザーが同じ質問を投稿したのは、彼がこの質問に十分な注意を払っていないと感じたからです。私は彼に彼の質問を削除するように頼み、より多くの答えを得るためにこの質問に報奨金を提供した。彼らがあなたの質問に答えるならば、以下の答えの1つを受け入れるのを忘れないでください。
テルドン

@terdonは賞金に感謝し、素晴らしい答えを生み出しました。私はまだすべてを慎重にテストしていませんが、その間Graemeの答えを受け入れます。
トーター14

回答:


56

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、2つのディレクトリがあります。1人がコールしblock、もう1人がコールしましたchar。ここで簡単なのは、これらがそれぞれブロックデバイスとキャラクターデバイス用であることです。各デバイスは、このディレクトリのメジャー/マイナー番号でアクセスできます。デバイスで使用可能なドライバがある場合driver、このdeviceディレクトリまたはサブディレクトリ内のリンクのターゲットを読み取ることで見つけることができます。たとえば、/dev/sda私の場合は簡単にできます:

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

これは、sdドライバーがデバイスに使用されていることを示しています。デバイスがブロックデバイスかキャラクターデバイスかわからない場合は、シェルでこの部分を単にに置き換えることができます*。これも同様に機能します。

$ 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 
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

最後に、質問から少し/sys逸脱するために、別のグロブトリックを追加して、どのドライバーがどのデバイスで使用されているかについて、より広い視野を取得します(ただし、デバイスファイルを持つドライバーとは限りません)。

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

使用されているすべてのドライバーを特定する方法はありますか?たとえば、udevadm答えはあなたsdとを与えますahciahci使用されているかどうかを判断する方法はありますか?
パトリック14

@Patrick、はい、更新されました。
グレアム14

すばらしい答え、ありがとう!ただ注意してください、私の場合、リンクはにあったdevice/device/ので、私のreadlinkコマンドはのように見えましたreadlink /sys/dev/char/XX\:Y/device/device/driver
ハリーカッツ

19

udevadmこのツールを使用して、これを発見できます。
コマンドはになりudevadm info -a -n /dev/sdaDRIVER==パラメーターを確認します。

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

これは、このデバイスを提供することに関与2人のドライバーが実際に存在していることを示している、sdahci。最初のものsdは、/dev/sdaデバイスに直接責任がありますが、ahciドライバーの下位を使用します。

 

udevadmコマンドの出力は次のようになり、動作の説明が含まれています。

# 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==""

1
@ECarterYoung udevadm削除された(または推奨された)場所はどこですか?そのことを示唆するものすら見つけることができません。
パトリック14

1
@ECarterYoung私がやった、私はこの種の何も見ない。
パトリック14

カーネルにUEVENT_HELPERが存在しないと間違えました。systemdを実行しているシステムでは、このエントリは空白ですが、ヘルパーはまだシステムに存在しています。
eyoung100 14

4

使用するコマンドhwinfoと出力モデルとドライバを。ドライバーがない場合は表示されません。たとえば、ディスクの場合:

#hwinfo --block | grep -Ei "driver \:| model \:"
  モデル:「フロッピーディスク」
  モデル:「FUJITSU MHZ2080B」
  ドライバー:「ahci」、「sd」
  モデル:「パーティション」
  モデル:「パーティション」
  モデル:「パーティション」
  モデル:「汎用マルチカード」
  ドライバー:「ums-realtek」、「sd」
  モデル:「Realtek USB2.0-CRW」
  ドライバー:「ums-realtek」

ネットワークカードの場合:

#hwinfo --netcard | grep -Ei "driver \:| model \:"
  モデル:「Broadcom NetXtreme BCM5764MギガビットイーサネットPCIe」
  ドライバー:「tg3」
  モデル:「Intel Wireless WiFi Link 5100」
  ドライバー: "iwlwifi"

USBデバイスの場合:

#hwinfo --usb | grep -Ei "driver \:| model \:"
  モデル:「Linux 3.11.10-7-desktop uhci_hcd UHCIホストコントローラー」
  ドライバー:「ハブ」
  モデル:「Linux 3.11.10-7-desktop uhci_hcd UHCIホストコントローラー」
  ドライバー:「ハブ」
  モデル:「IDEACOM IDC 6680」
  ドライバー:「usbhid」
  [...]

hwinfo --helpを使用して、クエリできる他のデバイスタイプを確認します。hwinfoはデフォルトでインストールされます(SUSE Linuxなど)。


これを特定のデバイスファイルに関連付けるには、1つの方法で--onlyオプションを追加します。例hwinfo --block --only /dev/sda | grep ...
グレアム14

3

lshwあなたのマシンで見つかったハードウェアをリストする素晴らしいツールです。実行する前に最初にインストールする必要があります。

$ yum install lshw
$ apt-get install lshw

使用している、yumまたはapt-get使用しているシステムに応じて。次に、ストレージハードウェアを具体的にリストするには:

# 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

rootすべての情報を取り戻すために実行することもできます。

それ以外の場合は、lspciハードウェアに関する情報も提供できます。

$ 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

デバイスのメジャー番号とマイナー番号を確認するには、デバイスで実行lsします。

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

この出力では、bin brw-rw----.はこれがブロックデバイスであることを意味します。数字80は、それぞれデバイスのメジャー番号とマイナー番号です。


1
私の質問は、1つのデバイスとそのモジュール/ドライバー間のリンクを見つけることです。どこで答えますか?
トーター14

1
両方の出力に@Totor lshwlspci設定:あなたは、デバイスによって使用されるモジュールを参照することができ、ドライバ= AHCIレイテンシ= 0使用中のカーネルドライバ:AHCIを
Spack 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.