USB 버스 번호와 장치 번호는 어떻게 할당 되었습니까?


19

사용 lsusb하면 USB 장치의 버스 번호와 장치 번호가 수시로 변경 될 수 있습니다. 내가 이해 한 바에 따르면, 재부팅 할 때마다 버스 번호를 변경할 수 있습니다. 다시 연결할 때마다 장치 번호가 변경됩니다.

내 질문은 시스템이 버스 번호와 장치 번호를 얻는 데 사용한 알고리즘은 무엇입니까? 특히 장치 번호는 단조입니까? OS를 재부팅하지 않고 다시 연결된 장치 중 하나가 다시 연결된 다른 장치의 이전 버스 번호와 장치 번호를 사용하고 있습니까?


6
한가지 궁금한 점이 있습니다. 재부팅 후 BUS 번호가 실제로 바뀌 었습니까? 항상 하드웨어를 변경하거나 BIOS를 업데이트하지 않으면 BUS 번호가 변경되지 않을 것이라고 확신했습니다. USB 버스는 단순히 PCI 버스에 연결된 허브 / 컨트롤러 (모든 경우에 내가 본 것 이상)이며 PCI 버스 정보는 BIOS에서 제공됩니다. 그러나 나는 틀렸을 수도 있습니다. 대답을하고 싶지 않습니다.
grochmal

하드웨어 변경이있을 때만 보입니다.
Conan

답변:


23

참고 : 이것은 Linux 답변입니다. 다른 커널은이를 처리하는 방법이 약간 다릅니다.

문맥

PCI 버스에 대해 이야기하지 않고 USB 버스에 대해 이야기하는 것은 어렵습니다. CPU는 USB 버스와 통신 할 수 없습니다. CPU가 연결된 USB 컨트롤러가있는 PCI 버스 (USB 컨트롤러 / 허브는 lsusbUSB 버스라고 함)와 통신합니다. 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 개의 장치가 있습니다 lsusb! lspciUSB 컨트롤러 만 나열합니다. 컨트롤러에는 하나 이상의 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

이제 이것이 의미가 있습니다. PCI 버스에 장치로 연결된 7 개의 USB 컨트롤러가 있습니다. 예를 들어, 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커널은 로 돌아 가지 않고 대신 가장 적은 수의 장치 번호를 재사용합니다. 이 동작을 변경하는 쉬운 방법이 있습니까?
Conan

@Conan-흠 ... 글쎄, 내가 어떻게 말할 수 있습니다 : 나는 모른다. 나는 당신이했던 것처럼 장치 카운터를 오버플로하려고 시도하지 않았습니다. 그런 다음 다시 장치 번호를 알 필요가 없습니다. 예를 들어, 연결할 때 USB 드라이브를 찾으려고하면 파일 시스템 레이블 또는 UUID ( udev보다 이해하기 쉬운)로 수행해야합니다. 학습을위한 번호 매기기를 이해하기 위해 정보가있는 유일한 곳은 커널 코드라고 생각합니다.
grochmal

@grochmal에게 감사합니다. 테스트 오버플로가 발생했을 때 실수했다고 생각합니다. 이후 테스트에서 오버플로가 발생하면 카운터는 실제로 더 낮은 숫자에서 검색합니다.
Conan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.