Як знайти драйвер (модуль), пов’язаний із пристроєм в Linux?


50

У Linux дано:

  • пристрій, наприклад /dev/sda,
  • і його основні та незначні кількості, наприклад 8, 0,

як я можу знати, який модуль / драйвер "керує" ним?

Чи можу я розкопатись /sysабо /procвиявити це?


Якесь поєднання lsmod, /proc/modulesі modinfo?

4
stackoverflow.com/questions/2911050 виглядає так само, як це питання.
Майкл Томкінс


Тотор, я додав щедрості тому, що інший користувач розмістив те саме питання, тому що вважав, що цей не приділяв достатньої уваги. Я попросив його видалити його питання і запропонував щедро на це, щоб отримати більше відповідей. Будь ласка, не забудьте прийняти одну з відповідей нижче, якщо вони відповідають на ваше запитання.
terdon

@terdon дякую за щедроту, вона дала приємні відповіді. Я все ще не ретельно перевіряв, але тим часом прийму відповідь Graeme .
Тотор

Відповіді:


58

Щоб отримати цю інформацію sysfsдля файлу пристрою, спочатку визначте основне / другорядне число, поглянувши на вихід ls -l, наприклад,

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

Це 8, 0говорить нам, що основна кількість є, 8а другорядна є 0. На bпочатку списку також йдеться про те, що це блоковий пристрій. Інші пристрої можуть мати пристрій cдля символів на початку.

Якщо потім заглянути /sys/dev, ви побачите, що є два каталоги. Один дзвонив blockі один дзвонив 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для цього немає посилань).

І останнє, що може бути корисно зробити - це перерахувати драйвери для всіх пристроїв, для яких вони доступні. Для цього ви можете використовувати глобуси для вибору всіх каталогів, у яких є посилання на драйвери. Наприклад:

$ 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і ahci. Чи є спосіб визначити, ahciчи використовується також?
Патрік

@Patrick, так, оновлено.
Graeme

Чудова відповідь, дякую! Зауважимо лише, що в моєму випадку було посилання device/device/, тому моя readlinkкоманда виглядала так readlink /sys/dev/char/XX\:Y/device/device/driver.
Гаррі Коттс

19

Ви можете скористатися udevadmінструментом для виявлення цього.
Команда буде udevadm info -a -n /dev/sda, а потім подивіться на DRIVER==параметри.

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

Це показує, що насправді 2 драйвери беруть участь у наданні цього пристрою sdта ahci. Перший, 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видалено (або навіть рекомендується)? Я нічого не можу знайти, навіть натякаючи на це.
Патрік

1
@ECarterYoung Я це зробив, я нічого подібного не бачу.
Патрік

Я помилився з приводу відсутності UEVENT_HELPER в ядрі. У системах, на яких працює systemd, цей запис порожній, але довідник все ще присутній у системі.
eyoung100

4

Використовуйте команду hwinfo та вихідну модель та драйвер. Якщо немає драйвера, він не відображатиметься. Наприклад для дисків:

# hwinfo --блок | grep -Ei "драйвер \: | модель \:"
  Модель: "Дискета"
  Модель: "FUJITSU MHZ2080B"
  Драйвер: "ahci", "sd"
  Модель: "Перегородка"
  Модель: "Перегородка"
  Модель: "Перегородка"
  Модель: "Generic Multi-Card"
  Драйвер: "ums-realtek", "sd"
  Модель: "Realtek USB2.0-CRW"
  Драйвер: "ums-realtek"

Для мережевих карт:

# hwinfo --netcard | grep -Ei "драйвер \: | модель \:"
  Модель: "Broadcom NetXtreme BCM5764M Gigabit Ethernet PCIe"
  Драйвер: "tg3"
  Модель: "Intel Wireless WiFi Link 5100"
  Водій: "iwlwifi"

Для USB-пристроїв:

# hwinfo --usb | grep -Ei "драйвер \: | модель \:"
  Модель: "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.


Щоб пов’язати це з певним файлом пристрою, одним із способів є додавання --onlyпараметра. Напр hwinfo --block --only /dev/sda | grep ....
Graeme

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

У цьому висновку, то bв brw-rw----.означає , що це блоковий пристрій. Цифри 8і 0, відповідно, основна та незначна кількість пристрою.


1
Моє запитання полягає у пошуку зв’язку між одним пристроєм та його модулем / драйвером. Де ти на це відповідаєш?
Тотор

1
@Totor В обох висновках lshwта lspciви можете побачити модуль, який використовується пристроєм: конфігурація: драйвер = ahci latency = 0 та використовуваний драйвер ядра: ahci .
Spack
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.