2. Linux USB子系统架构

Linux USB 子系统采用经典的三层软件架构设计,从底层的硬件控制到上层的功能抽象,每一层都有明确的职责和接口。理解这三层划分是掌握 USB Host 驱动开发的基础。

2.1 三层架构总览

USB 子系统在逻辑上分为 USB 核心层(USB Core)、主机控制器驱动层(HCD) 和 设备驱动层(Gadget/Function)。核心层作为桥梁,向上为设备驱动提供统一 API,向下抽象不同主机控制器的差异。

Linux USB 子系统三层架构 设备驱动层(Device Driver Layer) USB 设备类驱动(HID、Mass Storage、CDC、Audio 等) Gadget Function 驱动(用于 Device 模式) USB 核心层(USB Core) USB 总线管理、设备枚举、配置管理 URB 管理、协议抽象、电源管理 ioctl 接口、sysfs 属性文件 主机控制器驱动层(HCD) xHCI / EHCI / OHCI / UHCI 驱动 寄存器操作、DMA 传输、中断处理 数据流方向:设备驱动 → USB Core → HCD → 硬件

2.2 各层职责详解

层次 核心文件/目录 主要职责 关键数据结构
设备驱动层 drivers/usb/class/
drivers/usb/gadget/
实现具体 USB 设备功能(键盘、存储、网卡等);注册为 USB 接口驱动;处理 URB 完成回调 usb_driver
usb_interface
USB 核心层 drivers/usb/core/ 设备枚举与配置;URB 生命周期管理;总线电源管理;提供 usb_* API 给设备驱动 usb_device
usb_bus
urb
HCD 层 drivers/usb/host/ 直接操作主机控制器寄存器;管理传输描述符环(Ring);处理硬件中断;实现 DMA 映射 usb_hcd
xhci_hcd
td

2.3 核心数据结构关系

三层之间的交互通过几个核心数据结构完成。下图展示了从设备驱动到硬件的关键数据流路径:

核心数据结构与数据流 设备驱动 usb_driver.probe() USB Core usb_submit_urb() HCD xhci_urb_enqueue() usb_interface urb 结构体 TRB / TD 数据流关键路径: 1. 设备驱动通过 usb_submit_urb() 提交 URB 到 USB Core 2. USB Core 将 URB 路由到对应主机控制器的 HCD 3. HCD 将 URB 转换为硬件传输描述符(TRB/TD)并提交到 DMA 环

2.4 URB:跨层通信的核心载体

URB(USB Request Block) 是 USB 子系统中最核心的跨层通信单元。它类似于网络协议栈中的 sk_buff,承载着从设备驱动到硬件控制器的所有传输请求。

URB 生命周期:

  1. 创建:设备驱动调用 usb_alloc_urb() 分配 URB 结构体
  2. 填充:设置传输类型(控制/批量/中断/等时)、目标端点、数据缓冲区、回调函数
  3. 提交:调用 usb_submit_urb() 将 URB 交给 USB Core
  4. 路由:USB Core 根据 URB 所属的 usb_device 找到对应的 HCD
  5. 硬件化:HCD 将 URB 拆解为硬件传输描述符(如 xHCI 的 TRB)
  6. 完成回调:硬件传输完成后,HCD 调用 URB 的回调函数通知设备驱动
// URB 结构体核心字段(简化)
struct urb {
    struct list_head urb_list;           // 链表节点
    struct usb_device *dev;              // 目标 USB 设备
    unsigned int pipe;                   // 管道(端点方向+类型)
    int status;                          // 传输状态
    unsigned int transfer_flags;         // 传输标志
    void *transfer_buffer;               // 数据缓冲区
    dma_addr_t transfer_dma;             // DMA 地址
    int transfer_buffer_length;          // 数据长度
    int actual_length;                   // 实际传输长度
    unsigned char *setup_packet;         // 控制传输设置包
    void *context;                       // 驱动私有数据
    usb_complete_t complete;             // 完成回调函数
};

2.5 设备驱动层:Gadget 与 Function

USB 子系统不仅支持 Host 模式,还支持 Gadget(设备)模式。在 Gadget 模式下,Linux 设备可以模拟为 USB 外设(如虚拟串口、虚拟网卡、大容量存储设备)。

模式 驱动层 典型场景 关键框架
Host 模式 设备驱动层(Device Driver) PC 连接 USB 鼠标、U 盘 usb_driver + usb_interface
Gadget 模式 Function 驱动层(Gadget Function) Android 手机模拟为 MTP 设备 usb_function + usb_composite_dev

注意:Gadget 模式下的 Function 驱动与 Host 模式下的设备驱动虽然概念对称,但实现框架完全不同。Function 驱动运行在 drivers/usb/gadget/ 目录下,使用 usb_ep(端点)和 usb_request 接口,而非 URB。

2.6 数据流全景示例

以 USB 大容量存储设备(U 盘)为例,展示一次读请求的完整数据流:

U盘读请求数据流示例 ① 文件系统层 ② usb-storage 驱动 ③ USB Core ④ xHCI HCD ⑤ 硬件控制器 详细流程说明: ① 文件系统层发起 SCSI READ 命令(通过块设备层) ② usb-storage 驱动将 SCSI 命令封装为 CBW,提交 URB ③ USB Core 将 URB 路由到 xHCI 主机控制器 ④ xHCI HCD 将 URB 转换为 Transfer TRB,写入 Event Ring ⑤ 硬件通过 DMA 读取数据,完成后触发中断 ⑥ HCD 中断处理函数获取完成事件,调用 URB 回调 ⑦ usb-storage 驱动解析 CSW,将数据返回给文件系统

2.7 关键 API 与接口

三层之间的接口定义清晰,下表列出各层之间的核心 API:

接口方向 API 函数 说明
设备驱动 → USB Core usb_submit_urb() 提交 URB 请求
设备驱动 → USB Core usb_control_msg() 发送控制传输(同步封装)
USB Core → HCD hc_driver->urb_enqueue() HCD 接收 URB 并处理
USB Core → HCD hc_driver->start() 启动主机控制器
HCD → USB Core usb_hcd_giveback_urb() HCD 将完成的 URB 返回给 Core
USB Core → 设备驱动 urb->complete() URB 完成回调函数

重要提示:URB 回调函数在中断上下文中执行,不能调用可能导致睡眠的函数(如 kmalloc(GFP_KERNEL)、mutex_lock())。如果需要执行耗时操作,必须使用工作队列(workqueue)或 tasklet 推迟处理。

2.8 本章小结

Linux USB 子系统的三层架构设计体现了软件工程中的分层抽象原则:

  • 设备驱动层 关注功能实现,无需关心硬件细节
  • USB 核心层 提供通用服务,管理总线生命周期
  • HCD 层 封装硬件差异,提供统一接口给上层

URB 作为跨层通信的核心载体,贯穿整个数据流路径。理解这三层划分和 URB 生命周期,是后续深入学习 xHCI 协议和驱动开发的前提。