Come sono stati assegnati il ​​numero del bus USB e il numero del dispositivo?


19

Quando uso lsusbmi rendo conto che il numero di bus e il numero di dispositivo di un dispositivo USB possono cambiare di volta in volta. Da quello che ho capito, il numero del bus può essere cambiato ad ogni riavvio. Il numero del dispositivo cambierà ad ogni riconnessione.

La mia domanda è quale algoritmo utilizzato dal sistema per ottenere il numero del bus e il numero del dispositivo? Soprattutto il numero del dispositivo, è monotonico? Ci sarà mai un caso in cui: senza riavviare il sistema operativo, un dispositivo ricollegato utilizza il vecchio numero di bus e il numero di dispositivo di un altro dispositivo ricollegato?


6
Una cosa mi ha incuriosito sulla tua domanda, hai visto davvero cambiare i numeri del BUS dopo un riavvio? Sono sempre stato fiducioso che se non si modifica l'hardware o si aggiorna il BIOS, i numeri BUS non cambieranno. I bus USB sono semplicemente hub / controller collegati ai bus PCI (in tutti i casi che ho visto almeno) e le informazioni sul bus PCI provengono dal BIOS. Ma potrei sbagliarmi, non voglio dare una risposta e parlare di merda.
grochmal

giusto, solo quando ho un cambiamento hardware sembra.
Conan,

Risposte:


23

Nota: questa è una risposta Linux ; altri kernel avranno un modo leggermente diverso di gestirlo.

Contesto

È difficile parlare di bus USB senza parlare di bus PCI. Una CPU non può comunicare con un bus USB, ciò che accade è che la CPU comunica con un bus PCI a cui è collegato un controller USB (e un controller / hub USB è ciò che lsusbchiama un bus USB). I bus PCI sono numerati in base alla distanza dalla CPU, ad esempio:

    +-----+
    | CPU |
    +-----+
       |              PCI Bus 0
 ---+--+-----------------------------+
    |                                |
+---+----+                      +----+---+
| Bridge |                      | Bridge |
+---+----+                      +----+---+
    |  PCI bus 1                     |  PCI bus 2
  --+--------+               +-------+-------------+
             |               |                     |
       Disk Controller    USB Controller      Network Card
         (Device 00)       (Device 00)         (Device 01)

Guardando dentro man lspcivediamo quanto segue:

   Slot   The  name of the slot where the device resides
          ([domain:]bus:device.function).  This tag is
          always the first in a record.

Pertanto ora sappiamo come interpretare i numeri PCI. Successivamente vedremo i controller USB collegati ai bus PCI. La macchina in cui mi trovo attualmente ha un'interessante configurazione USB, quindi la userò come esempio:

$ lspci -tv
-[0000:00]-+-00.0  Advanced Micro Devices, Inc. [AMD] RS780 Host Bridge
           +-01.0-[01]----05.0  Advanced Micro Devices, Inc. [AMD/ATI] RS780M [Mobility Radeon HD 3200]
           +-04.0-[02]----00.0  Qualcomm Atheros AR928X Wireless Network Adapter (PCI-Express)
           +-05.0-[03]----00.0  Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
           +-06.0-[04-06]--
           +-11.0  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode]
           +-12.0  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
           +-12.1  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0 USB OHCI1 Controller
           +-12.2  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller
           +-13.0  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
           +-13.1  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0 USB OHCI1 Controller
           +-13.2  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller
           +-14.0  Advanced Micro Devices, Inc. [AMD/ATI] SBx00 SMBus Controller
           +-14.1  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 IDE Controller
           +-14.2  Advanced Micro Devices, Inc. [AMD/ATI] SBx00 Azalia (Intel HDA)
           +-14.3  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 LPC host controller
           +-14.4-[07]--
           +-14.5  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI2 Controller
           +-18.0  Advanced Micro Devices, Inc. [AMD] Family 11h Processor HyperTransport Configuration
           +-18.1  Advanced Micro Devices, Inc. [AMD] Family 11h Processor Address Map
           +-18.2  Advanced Micro Devices, Inc. [AMD] Family 11h Processor DRAM Controller
           +-18.3  Advanced Micro Devices, Inc. [AMD] Family 11h Processor Miscellaneous Control
           \-18.4  Advanced Micro Devices, Inc. [AMD] Family 11h Processor Link Control

Aspetta aspetta aspetta, cosa sono tutti quei vantaggi? Nella parte superiore abbiamo il dominio e il bus PCI -[0000:00](questa macchina ha un solo bus PCI). E poi abbiamo diversi dispositivi collegati a quel bus. Vediamo quali sono i dispositivi USB:

$ lspci -tv | grep -i usb
       +-12.0  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
       +-12.1  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0 USB OHCI1 Controller
       +-12.2  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller
       +-13.0  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
       +-13.1  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0 USB OHCI1 Controller
       +-13.2  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller
       +-14.5  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI2 Controller

Bene, ora confrontiamo questo con lsusb(lo uso sortsolo per semplificare la ricerca nell'elenco in seguito):

$ lsusb | sort
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 174f:5a31 Syntek Sonix USB 2.0 Camera
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 002: ID 046d:c019 Logitech, Inc. Optical Tilt Wheel Mouse
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 002: ID 0b05:1751 ASUSTek Computer, Inc. BT-253 Bluetooth Adapter

Aspetta ancora. Abbiamo 7 dispositivi USB secondo lspcima 10 dispositivi secondo lsusb! lspcielenca solo i controller USB; un controller può avere più di un dispositivo USB collegato ad esso. Esploriamo /sys/bus/per vedere come questo accade.

$ ls -l /sys/bus/usb/devices/
... 1-0:1.0 -> ../../../devices/pci0000:00/0000:00:12.2/usb1/1-0:1.0
... 2-0:1.0 -> ../../../devices/pci0000:00/0000:00:13.2/usb2/2-0:1.0
... 2-1 -> ../../../devices/pci0000:00/0000:00:13.2/usb2/2-1
... 2-1:1.0 -> ../../../devices/pci0000:00/0000:00:13.2/usb2/2-1/2-1:1.0
... 2-1:1.1 -> ../../../devices/pci0000:00/0000:00:13.2/usb2/2-1/2-1:1.1
... 3-0:1.0 -> ../../../devices/pci0000:00/0000:00:12.0/usb3/3-0:1.0
... 3-1 -> ../../../devices/pci0000:00/0000:00:12.0/usb3/3-1
... 3-1:1.0 -> ../../../devices/pci0000:00/0000:00:12.0/usb3/3-1/3-1:1.0
... 4-0:1.0 -> ../../../devices/pci0000:00/0000:00:12.1/usb4/4-0:1.0
... 5-0:1.0 -> ../../../devices/pci0000:00/0000:00:13.0/usb5/5-0:1.0
... 6-0:1.0 -> ../../../devices/pci0000:00/0000:00:13.1/usb6/6-0:1.0
... 7-0:1.0 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-0:1.0
... 7-1 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-1
... 7-1:1.0 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-1/7-1:1.0
... 7-1:1.1 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-1/7-1:1.1
... 7-1:1.2 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-1/7-1:1.2
... 7-1:1.3 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-1/7-1:1.3
... usb1 -> ../../../devices/pci0000:00/0000:00:12.2/usb1
... usb2 -> ../../../devices/pci0000:00/0000:00:13.2/usb2
... usb3 -> ../../../devices/pci0000:00/0000:00:12.0/usb3
... usb4 -> ../../../devices/pci0000:00/0000:00:12.1/usb4
... usb5 -> ../../../devices/pci0000:00/0000:00:13.0/usb5
... usb6 -> ../../../devices/pci0000:00/0000:00:13.1/usb6
... usb7 -> ../../../devices/pci0000:00/0000:00:14.5/usb7

Ora sta iniziando a dare un senso, abbiamo 7 controller USB che sono collegati al bus PCI come dispositivi. Ad esempio, il bus USB 001 corrisponde al dispositivo PCI 0000:00:12.2e il bus USB 007 corrisponde al 0000:00:14.5dispositivo.

Numerazione del dispositivo

Le directory che iniziano con il numero del bus USB (ad es. 7-1:1.2) Sono i dispositivi effettivi collegati al controller USB. Proprio come un bus PCI può avere diversi dispositivi collegati, un controller USB (un hub) può avere diversi dispositivi USB collegati ad esso.

I numeri di dispositivo sono semplicemente contatori: il primo dispositivo connesso ottiene un 1, il successivo ottiene un 2 e così via. Ma c'è di più: l'USB è stato progettato per essere hot plug; pertanto è possibile connettere e disconnettere i dispositivi. Quando si disconnette un dispositivo USB, il numero del dispositivo non verrà più utilizzato dal kernel per nessun altro dispositivo su quel controller USB. Ad esempio, se si collega e si scollega una pen drive e si continua lsusba vedere, il numero del dispositivo per la pen drive aumenta.

Numerazione del bus

Se hai letto con attenzione quanto sopra, potresti chiederti una cosa che non ho toccato. L'ordine della numerazione PCI non corrisponde all'ordine in cui sono stati numerati i controller USB! Vediamolo di nuovo:

USB  | PCI
-----+----
usb1 | 0000:00/0000:00:12.2
usb2 | 0000:00/0000:00:13.2
usb3 | 0000:00/0000:00:12.0
usb4 | 0000:00/0000:00:12.1
usb5 | 0000:00/0000:00:13.0
usb6 | 0000:00/0000:00:13.1
usb7 | 0000:00/0000:00:14.5

L'elenco è in ordine, ma non del tutto. I primi due controller USB sembrano essere fuori servizio. Tuttavia, c'è una ragione per cui: se guardi lspcisopra, vedrai che quelli sono EHCIUSB (USB 2.0), mentre tutti gli altri controller OHCIUSB sono USB (USB 1.x).

Pertanto possiamo ridisegnare questa tabella come:

USB  | PCI
-----+----
usb1 | 0000:00/0000:00:12.2
usb2 | 0000:00/0000:00:13.2     USB 2.0
-----+---------------------------------
usb3 | 0000:00/0000:00:12.0     USB 1.x
usb4 | 0000:00/0000:00:12.1
usb5 | 0000:00/0000:00:13.0
usb6 | 0000:00/0000:00:13.1
usb7 | 0000:00/0000:00:14.5

E l'assegnazione dei numeri diventa chiara.


quindi cosa accadrà quando verrà utilizzato il numero massimo di numero di dispositivo. diciamo che continuo a ricollegare il mio dispositivo. Il numero del dispositivo andrà presto al massimo. In realtà ho fatto un test, sembra che non sia un semplice contatore. Non sta tornando a 001, invece il kernel sta riutilizzando il numero di dispositivo più grande. C'è un modo semplice per cambiare questo comportamento?
Conan,

@Conan - Hmm ... beh, come posso dirlo: non lo so. Non ho mai provato a traboccare il contatore del dispositivo come hai fatto tu. Ancora una volta, non è quasi necessario conoscere un numero di dispositivo in anticipo. Ad esempio, se stai cercando di trovare un'unità USB quando si collega, dovresti farlo tramite l'etichetta del filesystem o UUID (che udevcapisce anche più o meno). Per quanto riguarda la numerazione per motivi di apprendimento, credo che l'unico posto che abbia le informazioni sia il codice del kernel.
grochmal,

Grazie @grochmal, penso di aver fatto un errore durante il trabocco del test. I test successivi mi hanno mostrato in caso di overflow, il contatore ha effettivamente cercato dal numero più basso.
Conan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.