Writing an OS Kernel from Scratch | #345: USB Protocol — From HID to High-Speed Devices
Abstract: USB is essentially the “universal serial bus” for all peripherals, but many only know “plug and play.” This article takes you from physical layer topology, transfer types, xHCI controller, to practical lsusb usage, thoroughly understanding USB’s design philosophy and Linux practical skills.
1. USB Topology: Star Structure
USB uses a Star Topology — all devices connect through hubs to a root hub, then to the host controller. To software, it appears as a single bus — all devices share the same host controller bandwidth.
Why this design? USB’s core design goal is simplicity — devices don’t need to worry about bus arbitration; the host polls all devices. Each device has a unique address (1-127), using 4 transfer types to meet different bandwidth needs.
2. Four Transfer Types
| Type | Direction | Bandwidth | Latency | Typical Device |
|---|---|---|---|---|
| Control | Bidirectional | Low | Low | All devices (enumeration) |
| Interrupt | Unidirectional | Low | Determined | Keyboard, mouse |
| Bulk | Unidirectional | Variable | Uncertain | USB drives, printers |
| Isochronous | Unidirectional | Fixed | Determined | Cameras, audio |
Control Transfer: Enumeration’s Main Stage
Control transfers are USB’s “handshake protocol.” Every device must support them, with at least two endpoints: EP0 IN and EP0 OUT. Three stages: Setup → Data (optional) → Status.
Interrupt Transfer: Keyboard/Mouse Favorite
Interrupt endpoints are not hardware interrupts but polling — the host queries the device every 1-125ms (high/super speed) or 10ms (full speed). Keyboards and mice use this — predictable latency, no packet loss (with retry).
Comments