USB总线号和设备号如何分配?


19

使用时,lsusb我意识到USB设备的总线号和设备号可能会不时更改。据我了解,总线号可以在每次重启时更改。设备编号将在每次重新连接时更改。

我的问题是系统用来获取总线号和设备号的算法是什么?特别是设备号,单调吗?是否会出现以下情况:在不重新启动操作系统的情况下,一个重新连接的设备正在使用另一个重新连接的设备的旧总线号和设备号?


6
一件事使我对您的问题感到好奇,您是否真的看到重启后总线号发生了变化?我一直有信心,除非您更改硬件或更新BIOS,否则总线号不会改变。USB总线只是连接到PCI总线的集线器/控制器(至少在所有情况下我都看不到),而PCI总线信息来自BIOS。但是我可能是错的,不想回答,也不要胡扯。
grochmal

对,只有当我有硬件更改时才看起来像。
科南2016年

Answers:


23

注意:这是Linux的答案;其他内核将有稍微不同的方式来处理此问题。

语境

不谈论PCI总线就很难谈论USB总线。CPU无法与USB总线通信,发生的情况是CPU与与USB控制器相连的PCI总线通信(USB控制器/集线器lsusb称为USB总线)。PCI总线的编号基于它们与CPU的距离,例如:

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

从中man lspci可以看到以下内容:

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

因此,我们现在知道如何解释PCI编号。接下来,我们将研究连接到PCI总线的USB控制器。我当前所在的机器具有有趣的USB配置,因此我将使用它作为示例:

$ 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

等等等等,这些优点是什么?在顶部,我们具有域和PCI总线-[0000:00](该计算机只有一个PCI总线)。然后,我们将多个设备连接到该总线。让我们看看哪些是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

好,现在让我们将其与之比较lsusb(我sort只是为了使以后搜索列表更容易而使用):

$ 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

再等一下 我们有7个USB设备,lspci但有10个设备lsusblspci仅列出USB控制器;一台控制器可以连接多个USB设备。让我们探索/sys/bus/一下如何发生。

$ 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

现在这已经很有意义了,我们有7个USB控制器作为设备插入PCI总线。例如,USB总线001对应于PCI设备0000:00:12.2,USB总线007对应于0000:00:14.5设备。

设备编号

以USB总线号(例如7-1:1.2)开头的目录是连接到USB控制器的实际设备。就像PCI总线可以连接多个设备一样,USB控制器(集线器)也可以连接多个USB设备。

设备号只是计数器:连接的第一个设备为1,第二个为2,依此类推。但是还有一点:USB被设计为可热插拔;因此,您可以连接和断开设备。当您断开USB设备的连接时,内核将不再将该设备号用于该USB控制器上的任何其他设备。例如,如果您连接和断开笔式驱动器并继续操作,lsusb您将看到笔式驱动器的设备编号上升。

巴士编号

如果您仔细阅读了以上内容,您可能会想知道我没碰过的一件事。PCI编号的顺序与USB控制器的编号顺序不符!让我们再次看到:

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

该列表是按顺序排列的,但不完全相同。前两个USB控制器似乎故障。但是,有一个原因:如果您在lspci上面查看,您将看到它们是EHCIUSB(USB 2.0),而所有其他USB控制器都是OHCIUSB(USB 1.x)。

因此,我们可以将该表重绘为:

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

并且编号分配变得清晰。


所以当使用最大数量的设备号时会发生什么。假设我一直在重新连接设备。设备编号将很快达到最大值。我实际上做了一个测试,看起来它不是一个简单的计数器。它没有返回到001,而是内核正在重用最大的几个设备号。有没有简单的方法来更改此行为?
科南2016年

@柯南-嗯...好吧,我怎么说呢:我只是不知道。我从未尝试像您那样使设备计数器溢出。再说一次,几乎不需要事先知道设备号。例如,如果您试图在USB驱动器连接时找到它,则应该通过文件系统标签或UUID(甚至udev或多或少可以理解)来进行操作。至于为了学习而理解编号,我相信唯一具有该信息的地方是内核代码。
grochmal

谢谢@grochmal,我认为测试溢出时我犯了错误。后来的测试向我显示了溢出时的计数器确实从较低的数字开始搜索。
科南
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.