Writing an OS Kernel from Scratch | USB Protocol — From HID to High-Speed Devices

Have you ever wondered: When you plug in a mouse, how does the system know it’s a mouse and not a keyboard? Why can a USB drive be used immediately, but an old printer requires a driver to be installed? USB seems simple on the surface, but the protocol stack behind it is incredibly deep.

This article starts with USB’s tree topology, dissects transfer types, descriptors, the xHCI controller, and provides reproducible Linux debugging commands. After reading, you’ll discover that USB is not just “plug and play” — it’s a complete peripheral communication standard.


I. USB Physical Topology: Why Is It a Tree Structure

USB (Universal Serial Bus) is designed as a tree topology, expanded through Hubs, with each node being a device or Hub.

Bash
                      ┌─────────────┐
                      │   USB Host   │  ← Only 1 host (PC side)
                      │  (Controller)│
                      └──────┬──────┘
                             │ roothub
              ┌──────────────┼──────────────┐
              │              │              │
         ┌────▼───┐     ┌────▼───┐     ┌────▼────┐
         │ HubPort│     │HubPort │     │   Hub   │
         │   1   │     │   2   │     │ (Bus)   │
         └────┬───┘     └────┬───┘     └───┬────┘
              │              │            │
         ┌────▼───┐     ┌────▼───┐   ┌────▼────┐
         │  Keyboard│     │  Mouse  │   │   Hub   │
         │         │     │        │   │(Down×4) │
         └─────────┘     └────────┘   └───┬────┘
                                        │
                                   ┌────▼────┐
                                   │ Camera  │
                                   └─────────┘

Key constraints:

  • Each USB Host can connect up to 127 devices (including Hubs)
  • Each Hub port is an independent transaction; the Hub itself counts as one device
  • Full-speed (12Mbps)/High-speed (480Mbps)/SuperSpeed (5Gbps) are physical layer differences; the protocol layer is unified

II. Four Transfer Types: USB’s Different “Roads”

To meet different scenario requirements, USB defines four transfer types — like highways having fast lanes, slow lanes, and emergency lanes:

Bash
┌──────────────┬────────────┬──────────┬────────────┬──────────────────┐
│ Transfer Type │ Direction  │ Real-time │ Bandwidth   │ Typical Device    │
├──────────────┼────────────┼──────────┼────────────┼──────────────────┤
│ Control      │ Bidirectional│ Not guaranteed │ Low (1ms frame)│ Enumeration, config│
│ Interrupt    │ Bidirectional│ Guaranteed│ Low         │ Keyboard, Mouse   │
│ Bulk         │ Unidirectional│ Not guaranteed │ Remaining BW │ USB drive, Printer│
│ Isochronous  │ Unidirectional│ Guaranteed│ High BW     │ Camera, Audio     │
└──────────────┴────────────┴──────────┴────────────┴──────────────────┘

III. USB Descriptors: How Devices Tell the Host About Themselves

Bash
USB descriptor hierarchy:

  ┌──────────────────────────────────┐
  │  Device Descriptor               │
  │  - USB spec version              │
  │  - Vendor ID (VID) / Product ID (PID)  │
  │  - Number of configurations      │
  └──────────────┬───────────────────┘
                 │
                 ▼
  ┌──────────────────────────────────┐
  │  Configuration Descriptor        │
  │  - Power consumption             │
  │  - Number of interfaces          │
  └──────────────┬───────────────────┘
                 │
                 ▼
  ┌──────────────────────────────────┐
  │  Interface Descriptor            │
  │  - Interface class/subclass/protocol  │
  │  - HID: class=0x03               │
  │  - Mass Storage: class=0x08      │
  │  - Audio: class=0x01             │
  └──────────────┬───────────────────┘
                 │
                 ▼
  ┌──────────────────────────────────┐
  │  Endpoint Descriptor             │
  │  - Direction (IN/OUT)            │
  │  - Transfer type (Ctrl/Int/Bulk/Iso)  │
  │  - Max packet size               │
  │  - Polling interval              │
  └──────────────────────────────────┘

IV. xHCI Controller: The Core of USB 3.0

Bash
xHCI (eXtensible Host Controller Interface):

  Compared to EHCI/UHCI/OHCI (USB 2.0), xHCI:
  - Unifies USB 1.x/2.0/3.0 in one controller
  - Supports all transfer types
  - More efficient TRB (Transfer Request Block) management
  - Supports native USB 3.0 SuperSpeed (5Gbps)

  xHCI key data structures:
  - Device Context Base Address Array (DCBAA)
  - Input/Output Device Context (DC)
  - Transfer Ring (TRB ring)
  - Event Ring

Linux commands to check USB:
  $ lsusb           # List all USB devices
  $ lsusb -t        # Show USB topology
  $ usb-devices     # Detailed device information
  $ dmesg | grep usb # Kernel USB messages
  $ cat /sys/kernel/debug/usb/devices # All USB descriptors
Last modified: 2024年6月15日

Author

Comments

Write a Reply or Comment

Your email address will not be published.