跳到主要内容 Linux USB 驱动架构详解 | 极客日志
C
Linux USB 驱动架构详解 本文详细阐述了 Linux USB 子系统的三大架构:主机驱动、设备驱动和 Gadget 驱动。内容包括主机控制器类型、USB 核心层功能、URB 管理机制、设备枚举流程、关键数据结构定义以及 ConfigFS 配置接口。此外还总结了开发实践建议与调试技巧,旨在帮助开发者深入理解分层机制,掌握高质量 USB 驱动的开发与调试方法。
小熊软糖 发布于 2026/3/28 更新于 2026/4/14 1 浏览Linux USB 驱动架构详解
概述
Linux USB 子系统是 Linux 内核中最复杂的子系统之一,它支持 USB 主机模式、设备模式和 OTG 模式。USB 驱动架构分为三个主要部分:USB 主机驱动、USB 设备驱动和 USB Gadget 驱动。本文将深入分析这三个部分的工作原理和实现机制。
1. USB 主机驱动架构
1.1 USB 主机控制器类型
USB 主机控制器(Host Controller Device, HCD)是 USB 主机侧的核心组件,负责管理 USB 总线上的所有通信。Linux 内核支持多种类型的 USB 主机控制器:
1.1.1 不同类型的 HCD
OHCI (Open Host Controller Interface) :USB 1.1 标准,支持低速 (1.5Mbps) 和全速 (12Mbps) 设备
UHCI (Universal Host Controller Interface) :Intel 提出的 USB 1.1 标准,同样支持低速和全速设备
EHCI (Enhanced Host Controller Interface) :USB 2.0 标准,支持高速 (480Mbps) 设备
xHCI (eXtensible Host Controller Interface) :USB 3.0 及以上标准,支持超高速 (5Gbps) 设备
1.1.2 HCD 驱动架构 USB 设备驱动层 ↓ USB 核心层 (USB Core) ↓ 主机控制器驱动层 (HCD) ↓ 硬件层
1.2 USB 核心层 (USB Core) USB Core 是 USB 子系统的核心,提供以下功能:
1.2.1 设备枚举和管理
检测设备连接和断开
读取设备描述符信息
分配设备地址
配置设备参数
1.2.2 URB 管理 USB Request Block (URB) 是 USB 通信的基本单元:
struct urb {
struct kref kref ;
void *hcpriv;
struct list_head urb_list ;
struct usb_device *dev ;
unsigned int pipe;
int status;
unsigned int transfer_flags;
void *transfer_buffer;
dma_addr_t transfer_dma;
int transfer_buffer_length;
int actual_length;
unsigned char *setup_packet;
int start_frame;
int number_of_packets;
int interval;
int error_count;
void *context;
usb_complete_t complete;
};
1.2.3 驱动匹配机制
设备 ID 匹配 :基于 vendor ID 和 product ID
接口类匹配 :基于接口类别、子类别和协议
设备类匹配 :基于设备类别
1.3 HCD 驱动实现 以 xHCI 驱动为例,HCD 驱动需要实现以下关键函数:
static const struct hc_driver xhci_hc_driver = {
.description = "xhci-hcd" ,
.product_desc = "xHCI Host Controller" ,
.hcd_priv_size = sizeof (struct xhci_hcd),
.reset = xhci_reset,
.start = xhci_run,
.stop = xhci_stop,
.shutdown = xhci_shutdown,
.urb_enqueue = xhci_urb_enqueue,
.urb_dequeue = xhci_urb_dequeue,
.endpoint_disable = xhci_endpoint_disable,
.endpoint_reset = xhci_endpoint_reset,
.hub_status_data = xhci_hub_status_data,
.hub_control = xhci_hub_control,
.alloc_dev = xhci_alloc_dev,
.free_dev = xhci_free_dev,
.get_frame_number = xhci_get_frame_number,
.irq = xhci_irq,
};
2. USB 设备驱动模型
2.1 USB 设备层次结构 USB 设备 (Device)
├── 配置 (Configuration)
│ ├── 接口 (Interface)
│ │ ├── 端点 (Endpoint)
│ │ ├── 端点 (Endpoint)
│ │ └── ...
│ ├── 接口 (Interface)
│ └── ...
└── ...
2.1.1 设备描述符 struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__le16 idVendor;
__le16 idProduct;
__le16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
} __attribute__((packed));
2.1.2 接口描述符 struct usb_interface_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
} __attribute__((packed));
2.1.3 端点描述符 struct usb_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__le16 wMaxPacketSize;
__u8 bInterval;
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__((packed));
2.2 USB 驱动注册和匹配
2.2.1 USB 驱动结构 struct usb_driver {
const char *name;
int (*probe)(struct usb_interface *intf, const struct usb_device_id *id);
void (*disconnect)(struct usb_interface *intf);
int (*suspend)(struct usb_interface *intf, pm_message_t message);
int (*resume)(struct usb_interface *intf);
int (*pre_reset)(struct usb_interface *intf);
int (*post_reset)(struct usb_interface *intf);
const struct usb_device_id *id_table ;
struct usbdrv_wrap drvwrap ;
unsigned int no_dynamic_id:1 ;
unsigned int supports_autosuspend:1 ;
unsigned int disable_hub_initiated_lpm:1 ;
const struct attribute_group **dev_groups ;
};
2.2.2 设备 ID 表 struct usb_device_id {
__u16 match_flags;
__u16 idVendor;
__u16 idProduct;
__u16 bcdDevice_lo;
__u16 bcdDevice_hi;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 bInterfaceNumber;
kernel_ulong_t driver_info;
};
2.3 USB 设备枚举过程 USB 设备枚举是 USB Core 自动完成的复杂过程:
2.3.1 枚举步骤
设备连接检测 :Hub 检测到设备连接
设备复位 :Hub 对设备进行复位操作
地址分配 :USB Core 为新设备分配唯一地址
描述符读取 :读取设备描述符获取基本信息
配置选择 :选择合适的配置
接口驱动匹配 :为每个接口寻找匹配的驱动
2.3.2 枚举过程中的关键函数
int usb_new_device (struct usb_device *udev) ;
int usb_configure_device (struct usb_device *udev) ;
int usb_probe_interface (struct usb_interface *intf) ;
3. USB Gadget 驱动框架
3.1 Gadget 驱动架构 USB Gadget 驱动使 Linux 系统能够作为 USB 设备工作,其架构分为多层:
Gadget Function 驱动层 ↓ Composite 层 (可选) ↓ Gadget Function API 层 ↓ UDC (USB Device Controller ) 驱动层 ↓ 硬件层
3.2 UDC 驱动 USB Device Controller (UDC) 驱动直接控制 USB 设备控制器硬件:
3.2.1 UDC 驱动结构 struct usb_gadget {
const struct usb_gadget_ops *ops ;
struct usb_ep *ep0 ;
struct list_head ep_list ;
enum usb_device_speed speed ;
enum usb_device_speed max_speed ;
unsigned int is_dualspeed:1 ;
unsigned int is_otg:1 ;
unsigned int is_a_peripheral:1 ;
unsigned int b_hnp_enable:1 ;
unsigned int a_hnp_support:1 ;
unsigned int a_alt_hnp_support:1 ;
const char *name;
struct device *dev ;
};
3.2.2 Gadget 操作函数 struct usb_gadget_ops {
int (*get_frame)(struct usb_gadget *gadget);
int (*wakeup)(struct usb_gadget *gadget);
int (*set_selfpowered)(struct usb_gadget *gadget, int is_selfpowered);
int (*vbus_session)(struct usb_gadget *gadget, int is_active);
int (*vbus_draw)(struct usb_gadget *gadget, unsigned mA);
int (*pullup)(struct usb_gadget *gadget, int is_on);
int (*ioctl)(struct usb_gadget *gadget, unsigned code, unsigned long param);
};
3.3 Gadget Function 驱动 Gadget Function 驱动实现具体的 USB 设备功能:
3.3.1 Function 驱动结构 struct usb_function {
const char *name;
struct usb_gadget_strings **strings ;
struct usb_descriptor_header **descriptors ;
struct usb_descriptor_header **hs_descriptors ;
struct usb_descriptor_header **ss_descriptors ;
int (*bind)(struct usb_configuration *, struct usb_function *);
void (*unbind)(struct usb_configuration *, struct usb_function *);
int (*set_alt)(struct usb_function *, unsigned interface, unsigned alt);
int (*get_alt)(struct usb_function *, unsigned interface);
void (*disable)(struct usb_function *);
int (*setup)(struct usb_function *, const struct usb_ctrlrequest *);
void (*suspend)(struct usb_function *);
void (*resume)(struct usb_function *);
struct usb_configuration *config ;
struct list_head list ;
struct usb_ep *ep0 ;
struct list_head ep_list ;
};
3.3.2 常用 Function 驱动
mass_storage :U 盘功能
acm :USB 串口功能
rndis :USB 网络功能
uac :USB 音频功能
uvc :USB 视频功能
3.4 Composite 框架 Composite 框架支持将多个 Function 组合成一个复合设备:
3.4.1 Composite 驱动结构 struct usb_composite_driver {
const char *name;
const struct usb_device_descriptor *dev ;
struct usb_gadget_strings **strings ;
int (*bind)(struct usb_composite_dev *cdev);
int (*unbind)(struct usb_composite_dev *cdev);
void (*suspend)(struct usb_composite_dev *cdev);
void (*resume)(struct usb_composite_dev *cdev);
int (*setup)(struct usb_composite_dev *cdev, const struct usb_ctrlrequest *ctrl);
struct usb_gadget_driver gadget_driver ;
unsigned needs_serial:1 ;
unsigned max_speed:4 ;
};
3.5 ConfigFS 配置接口 ConfigFS 提供了用户空间配置 Gadget 的接口:
3.5.1 ConfigFS 使用示例
mkdir /sys/kernel/config/usb_gadget/g1
cd /sys/kernel/config/usb_gadget/g1
echo 0x18d1 > idVendor
echo 0x4e11 > idProduct
mkdir configs/c.1
echo 120 > configs/c.1/MaxPower
mkdir functions /mass_storage.usb0
mkdir functions /acm.usb1
ln -s functions /mass_storage.usb0 configs/c.1/
ln -s functions /acm.usb1 configs/c.1/
echo "musb-hdrc.0.auto" > UDC
4. 核心数据结构总结
4.1 USB 核心数据结构关系 usb_device
├── usb_device_descriptor
├── usb_config
│ ├── usb_configuration
│ └── usb_interface
│ ├── usb_interface_descriptor
│ └── usb_host_endpoint
│ └── usb_endpoint_descriptor
└── usb_host_endpoint (ep0)
4.2 关键数据结构映射 内核结构 USB 规范 作用 usb_device Device 表示整个 USB 设备 usb_interface Interface 表示设备的一个功能接口 usb_host_endpoint Endpoint 表示数据传输的端点 urb Transfer 表示一次 USB 传输 usb_gadget Device Gadget 模式下的设备表示 usb_function Function Gadget 模式下的功能模块
4.3 驱动模型对比 特性 主机模式 设备模式 (Gadget) 控制器驱动 HCD 驱动 UDC 驱动 设备驱动 USB 设备驱动 Function 驱动 枚举过程 自动枚举 手动配置 复合设备 自动识别 Composite 框架 配置接口 内核内部 ConfigFS
5. 开发实践建议
5.1 USB 设备驱动开发
分析设备描述符 :使用 lsusb -v 命令获取设备详细信息
确定驱动类型 :根据接口类别或设备 ID 选择合适的匹配方式
实现基本功能 :probe、disconnect、urb 处理函数
处理错误情况 :URB 错误处理和设备状态管理
电源管理 :实现 suspend 和 resume 函数
5.2 Gadget 驱动开发
选择开发方式 :Legacy 方式或 ConfigFS 方式
确定功能需求 :选择合适的 Function 驱动或开发自定义 Function
配置描述符 :准备 USB 描述符信息
实现回调函数 :setup、set_alt、disable 等关键函数
测试验证 :使用 USB 协议分析仪进行验证
5.3 调试技巧
启用调试信息 :配置内核 USB 调试选项
使用调试工具 :usbmon、usbview 等工具
查看系统日志 :dmesg 和 syslog 中的 USB 相关信息
分析 URB 传输 :使用 usbmon 捕获 URB 传输数据
检查描述符 :验证 USB 描述符的正确性
6. 总结 Linux USB 驱动架构是一个高度模块化和分层的系统,通过清晰的接口定义实现了主机和设备模式的统一管理。理解 USB 协议规范、掌握核心数据结构、熟悉驱动框架是开发高质量 USB 驱动的关键。随着 USB 技术的不断发展,新的 USB 标准和功能不断涌现,开发者需要持续学习和跟进最新的技术趋势。
USB 驱动开发涉及硬件协议、内核编程、设备管理等多个方面,需要开发者具备扎实的理论基础和丰富的实践经验。通过深入理解本文介绍的架构原理和实现机制,开发者可以更好地开发和调试 USB 驱动程序。
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown 转 HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
HTML 转 Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
JSON美化和格式化 将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online