หมายเลขบัส USB และหมายเลขอุปกรณ์ได้รับการกำหนดอย่างไร?


19

เมื่อใช้lsusbฉันรู้ว่าหมายเลขบัสและหมายเลขอุปกรณ์ของอุปกรณ์ USB สามารถเปลี่ยนแปลงได้เป็นครั้งคราว จากสิ่งที่ฉันเข้าใจหมายเลขรถบัสสามารถเปลี่ยนแปลงได้ในการรีบูตทุกครั้ง หมายเลขอุปกรณ์จะเปลี่ยนไปทุกครั้งที่เชื่อมต่อ

คำถามของฉันคืออัลกอริธึมที่ระบบใช้เพื่อรับหมายเลขบัสและหมายเลขอุปกรณ์ โดยเฉพาะอย่างยิ่งหมายเลขอุปกรณ์มันเป็นเสียงเดียวหรือไม่ จะมีกรณีที่: โดยไม่ต้องรีบูตระบบปฏิบัติการอุปกรณ์หนึ่งที่เชื่อมต่ออีกเครื่องหนึ่งกำลังใช้หมายเลขบัสและหมายเลขอุปกรณ์เก่าของอุปกรณ์เชื่อมต่ออีกเครื่องหนึ่งหรือไม่


6
มีสิ่งหนึ่งที่ทำให้ฉันสงสัยเกี่ยวกับคำถามของคุณคุณเห็นว่าตัวเลข BUS เปลี่ยนแปลงจริง ๆ หลังจากรีบูตหรือไม่ ฉันมั่นใจเสมอว่าหากคุณไม่เปลี่ยนฮาร์ดแวร์หรืออัพเดต BIOS หมายเลข BUS จะไม่เปลี่ยนแปลง บัส USB เป็นเพียงฮับ / คอนโทรลเลอร์ที่เชื่อมต่อกับบัส PCI (ในทุกกรณีที่ฉันเห็นเป็นอย่างน้อย) และข้อมูลบัส PCI มาจาก BIOS แต่ฉันอาจจะผิดไม่ต้องการที่จะตอบและพูดคุยอึอยู่ในนั้น
grochmal

ถูกต้องเฉพาะเมื่อฉันมีการเปลี่ยนแปลงฮาร์ดแวร์ดูเหมือนว่า
โคนัน

คำตอบ:


23

หมายเหตุ: นี่คือคำตอบของLinux ; เมล็ดอื่น ๆ จะมีวิธีที่แตกต่างออกไปเล็กน้อยในการจัดการกับสิ่งนี้

บริบท

เป็นการยากที่จะพูดถึงบัส USB โดยไม่ต้องพูดถึงบัส PCI CPU ไม่สามารถพูดคุยกับบัส USB ได้สิ่งที่เกิดขึ้นคือ CPU พูดคุยกับบัส PCI ซึ่งมีคอนโทรลเลอร์ USB เชื่อมต่ออยู่ (และคอนโทรลเลอร์ 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 ต่อไปเราจะดูที่คอนโทรลเลอร์ USB ที่เชื่อมต่อกับบัส PCI เครื่องที่ฉันอยู่ในปัจจุบันมีการกำหนดค่า 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

รออีกครั้ง เรามีอุปกรณ์ USB 7 ตัวตามlspciแต่อุปกรณ์ 10 ตัวตามlsusb! lspciแสดงรายการคอนโทรลเลอร์ 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

ตอนนี้สิ่งนี้เริ่มมีเหตุผลแล้วเรามีคอนโทรลเลอร์ USB 7 ตัวที่ต่อกับบัส 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เช่นนั้น แต่เคอร์เนลจะนำหมายเลขอุปกรณ์ที่น้อยที่สุดมาใช้ใหม่ มีวิธีง่ายๆในการเปลี่ยนพฤติกรรมนี้หรือไม่?
โคนัน

@Conan - อืม ... ฉันจะพูดยังไงดี: ฉันไม่รู้ ฉันไม่เคยพยายามล้นตัวนับอุปกรณ์ที่คุณทำ จากนั้นอีกครั้งจึงไม่จำเป็นต้องทราบหมายเลขอุปกรณ์ล่วงหน้า ตัวอย่างเช่นหากคุณพยายามค้นหาไดรฟ์ USB เมื่อทำการเชื่อมต่อคุณควรทำการติดตั้งด้วยระบบไฟล์หรือ UUID (ซึ่งudevเข้าใจมากขึ้นหรือน้อยลง) เพื่อทำความเข้าใจกับการลำดับเลขเพื่อประโยชน์ในการเรียนรู้ฉันเชื่อว่าที่เดียวที่มีข้อมูลคือรหัสเคอร์เนล
grochmal

ขอบคุณ @ grochmal ฉันคิดว่าฉันทำผิดพลาดเมื่อทดสอบล้น การทดสอบในภายหลังแสดงให้ฉันเห็นเมื่อล้นตัวนับจะค้นหาจากจำนวนที่ต่ำกว่า
โคนัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.