web-dev-qa-db-fra.com

Comment trouver le pilote (module) associé à un périphérique sous Linux?

Sous Linux, étant donné:

  • un appareil, par exemple /dev/sda,
  • et ses nombres majeur et mineur, par exemple 8, 0,

comment savoir quel module/pilote le "pilote"?

Puis-je creuser dans /sys ou /proc pour découvrir ça?

53
Totor

Pour obtenir ces informations de sysfs pour un fichier de périphérique, déterminez d'abord le nombre majeur/mineur en consultant la sortie de ls -l, par exemple

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

Le 8, 0 nous dit que le nombre majeur est 8 et le mineur est 0. Le b au début de la liste nous indique également qu'il s'agit d'un périphérique bloc. D'autres périphériques peuvent avoir un c pour le périphérique de caractères au début.

Si vous regardez alors sous /sys/dev, vous verrez qu'il y a deux répertoires. Un appelé block et un appelé char. Le plus évident ici est que ce sont respectivement pour les périphériques de bloc et de caractère. Chaque appareil est alors accessible par son numéro majeur/mineur est ce répertoire. Si un pilote est disponible pour le périphérique, il peut être trouvé en lisant la cible du lien driver dans ce sous-répertoire device. Par exemple, pour mon /dev/sda Je peux simplement faire:

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

Cela montre que le pilote sd est utilisé pour le périphérique. Si vous ne savez pas si le périphérique est un bloc ou un périphérique de caractères, dans le Shell, vous pouvez simplement remplacer cette partie par un *. Cela fonctionne aussi bien:

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

Les périphériques de bloc sont également accessibles directement via leur nom via /sys/block ou /sys/class/block. Par exemple:

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

Notez que l'existence de divers répertoires dans /sys peut changer en fonction de la configuration du noyau. De plus, tous les périphériques n'ont pas de sous-dossier device. Par exemple, c'est le cas pour les fichiers de périphérique de partition comme /dev/sda1. Ici, vous devez accéder à l'appareil pour l'ensemble du disque (malheureusement, il n'y a pas de lien sys pour cela).

Une dernière chose qui peut être utile est de répertorier les pilotes pour tous les périphériques pour lesquels ils sont disponibles. Pour cela, vous pouvez utiliser des globes pour sélectionner tous les répertoires dans lesquels les liens du pilote sont présents. Par exemple:

$ 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

Enfin, pour diverger un peu de la question, j'ajouterai un autre /sys astuce glob pour obtenir une perspective beaucoup plus large sur quels pilotes sont utilisés par quels périphériques (mais pas nécessairement ceux avec un fichier de périphérique):

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

Mise à jour

En regardant de plus près la sortie de udevadm, cela semble fonctionner en trouvant le canonical /sys répertoire (comme vous obtiendriez si vous déréférenciez les répertoires majeurs/mineurs ci-dessus), puis remontait l'arborescence des répertoires, imprimant toutes les informations qu'il trouve. De cette façon, vous obtenez des informations sur les périphériques parents et les pilotes qu'ils utilisent également.

Pour expérimenter cela, j'ai écrit le script ci-dessous pour parcourir l'arborescence des répertoires et afficher des informations à chaque niveau pertinent. udev semble rechercher des fichiers lisibles à chaque niveau, avec leurs noms et contenus incorporés dans ATTRS. Au lieu de cela, j'affiche le contenu des fichiers uevent à chaque niveau (apparemment, la présence de ceci définit un niveau distinct plutôt qu'un simple sous-répertoire). Je montre également le nom de base de tous les liens de sous-système que je trouve et cela montre comment l'appareil s'intègre dans cette hiérarchie. udevadm n'affiche pas les mêmes informations, c'est donc un bel outil complémentaire. Les informations du périphérique parent (par exemple PCI informations) sont également utiles si vous souhaitez faire correspondre la sortie d'autres outils tels que lshw à des périphériques de niveau supérieur.

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

Vous pouvez utiliser l'outil udevadm pour le découvrir.
La commande serait udevadm info -a -n /dev/sda, puis regardez le DRIVER== paramètres.

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

Cela montre qu'il existe en fait 2 pilotes impliqués dans la fourniture de ce périphérique, sd et ahci. Le premier, sd est directement responsable du /dev/sda périphérique, mais il utilise le pilote ahci sous-jacent.

La sortie de la commande udevadm ressemble à ceci et comprend une description de son fonctionnement.

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

Utilisez la commande hwinfo et le modèle de sortie et le pilote. S'il n'y a pas de pilote, il ne sera pas affiché. Par exemple pour les disques:

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

Pour les cartes réseau:

 # hwinfo --netcard | grep -Ei "pilote \: | modèle \:" 
 Modèle: "Broadcom NetXtreme BCM5764M Gigabit Ethernet PCIe" 
 Pilote: "tg3" 
 Modèle: "Intel Wireless WiFi Link 5100 "
 Pilote:" iwlwifi "

Pour les périphériques 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" 
 Pilote: "hub" 
 Modèle: "IDEACOM IDC 6680" 
 Pilote: "usbhid" 
 [...] 

Utilisez hwinfo --help pour savoir quels autres types d'appareils vous pouvez interroger. hwinfo est installé par défaut, par ex. sous SUSE Linux.

5
Thorsten Staerk

lshw est un outil génial pour répertorier le matériel trouvé sur votre machine. Vous devrez d'abord l'installer avant de lancer.

$ yum install lshw
$ apt-get install lshw

Utilisez yum ou apt-get selon le système que vous utilisez. Ensuite, pour répertorier spécifiquement le matériel de stockage:

# 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

Vous pouvez l'exécuter en tant que root pour récupérer toutes les informations.

Sinon, lspci peut également fournir des informations sur votre matériel:

$ 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

Pour connaître le numéro majeur et mineur d'un périphérique, exécutez simplement ls dessus.

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

Dans cette sortie, le b in brw-rw----. signifie qu'il s'agit d'un périphérique bloc. Les chiffres 8 et 0 sont respectivement le numéro majeur et le numéro mineur de l'appareil.

3
Spack