Bagaimana menemukan driver (modul) yang terkait dengan perangkat di Linux?

50

Di Linux, diberikan:

  • perangkat, misalnya /dev/sda,
  • dan angka mayor dan minornya, misalnya 8, 0,

bagaimana saya bisa tahu modul / driver mana yang "mengemudi" itu?

Dapatkah saya menggali /sysatau /procmenemukan itu?

Totor
sumber
Kombinasi dari lsmod, /proc/modulesdan modinfo?
4
stackoverflow.com/questions/2911050 terlihat sama dengan pertanyaan ini.
Michael Tomkins
Totor, saya menambahkan hadiah karena pengguna lain memposting pertanyaan yang sama karena dia merasa bahwa yang ini belum menerima perhatian yang cukup. Saya memintanya untuk menghapus pertanyaannya dan menawarkan hadiah yang satu ini untuk mendapatkan lebih banyak jawaban. Harap ingat untuk menerima salah satu jawaban di bawah jika mereka menjawab pertanyaan Anda.
terdon
@terdon terima kasih atas hadiahnya, itu menghasilkan jawaban yang bagus. Saya belum menguji semuanya dengan hati-hati, tetapi akan menerima jawaban Graeme sementara itu.
Totor

Jawaban:

58

Untuk mendapatkan informasi ini dari sysfsfile perangkat, pertama-tama tentukan angka utama / minor dengan melihat output ls -l, misalnya

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

The 8, 0memberitahu kita bahwa jumlah utama adalah 8dan minor adalah 0. Di bawal daftar juga memberi tahu kami bahwa itu adalah perangkat blok. Perangkat lain mungkin memiliki cperangkat karakter untuk di awal.

Jika Anda kemudian melihat ke bawah /sys/dev, Anda akan melihat ada dua direktori. Satu memanggil blockdan satu memanggil char. No-brainer di sini adalah untuk perangkat blok dan karakter. Setiap perangkat kemudian dapat diakses dengan nomor utama / minornya adalah direktori ini. Jika ada driver yang tersedia untuk perangkat, itu dapat ditemukan dengan membaca target drivertautan di devicesub-direktori ini atau . Misalnya, untuk saya, /dev/sdasaya cukup melakukannya:

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

Ini menunjukkan bahwa sddriver digunakan untuk perangkat. Jika Anda tidak yakin apakah perangkat tersebut adalah perangkat blok atau karakter, di shell Anda dapat dengan mudah mengganti bagian ini dengan a *. Ini juga berfungsi:

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

Perangkat blok juga dapat diakses langsung melalui namanya melalui salah satu /sys/blockatau /sys/class/block. Misalnya:

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

Perhatikan bahwa keberadaan berbagai direktori di /sysdapat berubah tergantung pada konfigurasi kernel. Juga tidak semua perangkat memiliki devicesubfolder. Misalnya, ini adalah kasus untuk file perangkat partisi seperti /dev/sda1. Di sini Anda harus mengakses perangkat untuk seluruh disk (sayangnya tidak ada systautan untuk ini).

Hal terakhir yang dapat berguna untuk dilakukan adalah membuat daftar driver untuk semua perangkat yang tersedia. Untuk ini, Anda dapat menggunakan gumpalan untuk memilih semua direktori di mana tautan driver ada. Misalnya:

$ 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

Akhirnya, untuk menyimpang dari pertanyaan sedikit, saya akan menambahkan /systrik gumpalan lain untuk mendapatkan perspektif yang lebih luas tentang driver yang digunakan oleh perangkat mana (meskipun tidak harus mereka yang memiliki file perangkat):

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

Memperbarui

Melihat lebih dekat pada output dari udevadm, tampaknya berfungsi dengan menemukan /sysdirektori kanonik (seperti yang akan Anda dapatkan jika Anda mereferensikan direktori utama / minor di atas), kemudian bekerja dengan cara menaiki pohon direktori, mencetak semua informasi yang ditemukan. Dengan cara ini Anda mendapatkan informasi tentang perangkat induk dan driver apa pun yang mereka gunakan juga.

Untuk bereksperimen dengan ini saya menulis skrip di bawah ini untuk menaiki pohon direktori dan menampilkan informasi pada setiap tingkat yang relevan. udevtampaknya mencari file yang dapat dibaca di setiap tingkat, dengan nama dan isinya dimasukkan ATTRS. Alih-alih melakukan ini, saya menampilkan konten ueventfile di setiap tingkat (tampaknya keberadaan ini mendefinisikan tingkat yang berbeda daripada hanya subdirektori). Saya juga menunjukkan nama samaran dari tautan subsistem yang saya temukan dan ini menunjukkan bagaimana perangkat ini cocok dengan hierarki ini. udevadmtidak menampilkan informasi yang sama, jadi ini adalah alat pelengkap yang bagus. Informasi perangkat induk (mis. PCIInformasi) juga berguna jika Anda ingin mencocokkan output alat lain seperti lshwke perangkat tingkat yang lebih tinggi.

#!/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
sumber
Apakah ada cara untuk menentukan semua driver yang digunakan? Seperti misalnya udevadmjawabannya akan memberi Anda sddan ahci. Apakah ada cara untuk menentukan ahciapakah digunakan juga?
Patrick
@ Patrick, ya, diperbarui.
Graeme
Jawaban yang bagus, terima kasih! Sebagai catatan, dalam kasus saya tautannya ada device/device/, jadi readlinkperintah saya terlihat seperti readlink /sys/dev/char/XX\:Y/device/device/driver.
Harry Cutts
19

Anda dapat menggunakan udevadmalat untuk menemukan ini.
Perintahnya adalah udevadm info -a -n /dev/sda, dan kemudian lihat DRIVER==parameternya.

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

Ini menunjukkan bahwa sebenarnya ada 2 driver yang terlibat dalam menyediakan perangkat ini, sddan ahci. Yang pertama, sdbertanggung jawab langsung untuk /dev/sdaperangkat, tetapi menggunakan ahcidriver di bawahnya.

 

Output dari udevadmperintah terlihat seperti ini, dan termasuk deskripsi cara kerjanya.

# 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
sumber
1
@ECarterYoung Di mana Anda melihat yang udevadmdihapus (atau bahkan disarankan)? Saya tidak dapat menemukan apa pun yang bahkan memberi isyarat pada hal itu.
Patrick
1
@ECarterYoung saya lakukan, saya tidak melihat hal semacam itu.
Patrick
Saya keliru tentang tidak adanya UEVENT_HELPER di kernel. Pada sistem yang menjalankan systemd, entri ini kosong, tetapi helpr masih ada di sistem.
eyoung100
4

Gunakan perintah hwinfo dan model output dan driver. Jika tidak ada driver itu tidak akan ditampilkan. Misalnya untuk disk:

# hwinfo --block | grep -Ei "driver \: | model \:"
  Model: "Floppy Disk"
  Model: "FUJITSU MHZ2080B"
  Pengemudi: "ahci", "sd"
  Model: "Partisi"
  Model: "Partisi"
  Model: "Partisi"
  Model: "Multi-Card Generik"
  Driver: "ums-realtek", "sd"
  Model: "Realtek USB2.0-CRW"
  Pengemudi: "ums-realtek"

Untuk kartu jaringan:

# hwinfo --netcard | grep -Ei "driver \: | model \:"
  Model: "Broadcom NetXtreme BCM5764M Gigabit Ethernet PCIe"
  Pengemudi: "tg3"
  Model: "Intel Wireless WiFi Link 5100"
  Pengemudi: "iwlwifi"

Untuk perangkat USB:

# hwinfo --usb | grep -Ei "driver \: | model \:"
  Model: "Linux 3.11.10-7-desktop uhci_hcd UHCI Host Controller"
  Driver: "hub"
  Model: "Linux 3.11.10-7-desktop uhci_hcd UHCI Host Controller"
  Driver: "hub"
  Model: "IDEACOM IDC 6680"
  Driver: "usbhid"
  [...]

Gunakan hwinfo --help untuk mencari tahu tipe perangkat lain apa yang dapat Anda tanyakan. hwinfo diinstal secara default misalnya pada SUSE Linux.

Thorsten Staerk
sumber
Untuk menghubungkan ini dengan file perangkat tertentu, salah satu caranya adalah menambahkan --onlyopsi. Misalnya hwinfo --block --only /dev/sda | grep ....
Graeme
3

lshwadalah alat yang luar biasa untuk membuat daftar perangkat keras yang ditemukan di mesin Anda. Anda harus menginstalnya terlebih dahulu sebelum dijalankan.

$ yum install lshw
$ apt-get install lshw

Gunakan yumatau apt-gettergantung pada sistem yang Anda gunakan. Kemudian untuk secara khusus mencantumkan perangkat keras penyimpanan:

# 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

Anda mungkin ingin menjalankannya rootuntuk mendapatkan semua informasi kembali.

Jika tidak, lspcidapat juga memberikan informasi tentang perangkat keras Anda:

$ 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

Untuk mengetahui jumlah besar dan kecil suatu perangkat, jalankan lssaja.

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

Dalam output ini, bin brw-rw----.berarti bahwa ini adalah perangkat blok. Digit 8dan 0masing-masing nomor utama dan kecil perangkat.

Spack
sumber
1
Pertanyaan saya adalah tentang menemukan tautan antara satu perangkat dan modul / drivernya. Di mana Anda menjawab itu?
Totor
1
@ Motor Dalam kedua output dari lshwdan lspciAnda dapat melihat modul yang digunakan oleh perangkat: konfigurasi: driver = ahci latency = 0 dan driver Kernel yang digunakan: ahci .
Spack