GNU/Linux >> Linux Esercitazione >  >> Linux

Come trovare il driver (modulo) associato a un dispositivo su Linux?

Per ottenere queste informazioni da sysfs per un file di dispositivo, per prima cosa determina il numero maggiore/minore osservando l'output di ls -l , ad esempio

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

Il 8, 0 ci dice che il numero maggiore è 8 e il minore è 0 . Il b all'inizio del listato ci dice anche che si tratta di un dispositivo a blocchi. Altri dispositivi potrebbero avere un c per dispositivo carattere all'inizio.

Se poi guardi sotto /sys/dev , vedrai che ci sono due directory. Uno chiamato block e uno chiamato char . Il gioco da ragazzi qui è che questi sono rispettivamente per dispositivi a blocchi e caratteri. Ogni dispositivo è quindi accessibile dal suo numero maggiore/minore in questa directory. Se è disponibile un driver per il dispositivo, può essere trovato leggendo il target del driver link in questo o nel device sottodirectory. Ad esempio, per il mio /dev/sda Posso semplicemente fare:

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

Ciò dimostra che il file sd driver viene utilizzato per il dispositivo. Se non sei sicuro che il dispositivo sia un dispositivo a blocchi oa caratteri, nella shell puoi semplicemente sostituire questa parte con un * . Funziona altrettanto bene:

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

È inoltre possibile accedere direttamente ai dispositivi a blocchi tramite il loro nome tramite /sys/block o /sys/class/block . Ad esempio:

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

Si noti che l'esistenza di varie directory in /sys può cambiare a seconda della configurazione del kernel. Inoltre, non tutti i dispositivi hanno un device sottocartella. Ad esempio, questo è il caso dei file del dispositivo di partizione come /dev/sda1 . Qui devi accedere al dispositivo per l'intero disco (purtroppo non ci sono sys link per questo).

Un'ultima cosa che può essere utile fare è elencare i driver per tutti i dispositivi per i quali sono disponibili. Per questo è possibile utilizzare i glob per selezionare tutte le directory in cui sono presenti i collegamenti dei driver. Ad esempio:

$ 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

Infine, per discostarsi un po' dalla domanda, aggiungerò un altro /sys glob per ottenere una prospettiva molto più ampia su quali driver vengono utilizzati da quali dispositivi (anche se non necessariamente quelli con un file di dispositivo):

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

Aggiorna

Osservando più da vicino l'output di udevadm , sembra funzionare trovando il /sys canonico directory (come si otterrebbe se si dereferenziassero le directory principali/minori sopra), quindi risalendo l'albero delle directory, stampando tutte le informazioni che trova. In questo modo ottieni informazioni sui dispositivi dei genitori e anche sui driver che utilizzano.

Per sperimentare questo ho scritto lo script qui sotto per risalire l'albero delle directory e visualizzare le informazioni a ogni livello rilevante. udev sembra cercare file leggibili ad ogni livello, con i loro nomi e contenuti incorporati in ATTRS . Invece di fare questo, visualizzo il contenuto del uevent file a ogni livello (apparentemente la presenza di questo definisce un livello distinto piuttosto che solo una sottodirectory). Mostro anche il nome di base di tutti i collegamenti del sottosistema che trovo e questo mostra come il dispositivo si inserisce in questa gerarchia. udevadm non visualizza le stesse informazioni, quindi questo è un ottimo strumento complementare. Le informazioni sul dispositivo principale (ad es. PCI information) è utile anche se vuoi abbinare l'output di altri strumenti come lshw a dispositivi di livello superiore.

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

Puoi usare il udevadm strumento per scoprirlo.
Il comando sarebbe udevadm info -a -n /dev/sda , quindi guarda DRIVER== parametri.

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

Ciò dimostra che in realtà ci sono 2 driver coinvolti nella fornitura di questo dispositivo, sd e ahci . Il primo, sd è direttamente responsabile del /dev/sda dispositivo, ma utilizza il ahci conducente sotto.

L'output del file udevadm Il comando ha questo aspetto e include una descrizione di come funziona.

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

Utilizzare il comando hwinfo e il modello di output e il driver. Se non è presente alcun driver, non verrà visualizzato. Ad esempio per i dischi:

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

Per le schede di rete:

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

Per dispositivi 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"
  [...]

Usa hwinfo --help per scoprire quali altri tipi di dispositivi puoi interrogare. hwinfo è installato per impostazione predefinita, ad es. su SUSE Linux.


Linux
  1. Come trovare file duplicati in Linux? L'aiuto è qui con il comando fdupes!

  2. Come trovare il modulo del kernel per un determinato dispositivo?

  3. Come utilizzare il comando trova di Linux per trovare i file

  4. Come trovare tutti i file sparsi in Linux

  5. Come reindirizzare i risultati di "trova" a mv in Linux

Come trovare applicazioni installate con dimensioni installate in Linux

Come trovare il numero di porta di un servizio in Linux

Come trovare la dimensione totale di una directory in Linux

Come trovare file con il comando fd in Linux

Come trovare l'elenco dei repository installati in Linux

Come modificare la password di root in Linux