1. USB Gadget 基础概念
USB Gadget 是嵌入式 Linux 系统中一个极为重要的概念。简单来说,USB Gadget 允许一台嵌入式设备(如开发板、路由器、手机)通过 USB 接口模拟成各种常见的 USB 外设,例如 U 盘、网卡、串口或键盘鼠标。这使得设备在物理上作为 Host 连接 USB 外设的同时,也能在另一条 USB 线上扮演 Device 角色。
1.1 什么是 USB Gadget
在 USB 协议体系中,任何 USB 系统都包含一个 Host(主机) 和至少一个 Device(设备)。传统 PC 作为 Host,U 盘作为 Device。而 USB Gadget 技术则让嵌入式设备能够运行 Gadget 驱动程序,利用硬件中的 UDC(USB Device Controller) 模块,将自己伪装成一个标准的 USB 设备。
1.2 Gadget 与 Host 的区别
理解 Gadget 与 Host 的本质区别是排查故障的基础。两者在硬件角色、软件栈、电气特性以及通信发起方式上存在根本不同。
| 对比维度 | USB Host | USB Gadget (Device) |
|---|---|---|
| 硬件控制器 | EHCI / XHCI / OHCI / UHCI | UDC (USB Device Controller) |
| 电气角色 | 提供 VBUS 电源 (5V) | 消耗 VBUS 电源 (或自供电) |
| 通信发起 | 主动发起所有事务 (Token) | 被动响应 Host 请求 |
| 软件栈 | USB Core → HCD → 设备驱动 | Gadget Core → UDC 驱动 → Function 驱动 |
| 枚举过程 | 检测设备插入 → 复位 → 分配地址 → 读取描述符 | 响应复位 → 接收地址 → 返回描述符 |
| 典型设备 | PC、笔记本、OTG 主设备 | U 盘、鼠标、键盘、手机 |
1.3 常见 Gadget 类型
Linux Gadget 框架支持多种功能类型,每种类型对应不同的 USB 类规范和实际应用场景。以下是四种最常用的 Gadget 类型。
1.3.1 大容量存储 Gadget (Mass Storage Gadget)
模拟 U 盘或移动硬盘。Host 将其识别为 SCSI 磁盘设备,可以直接进行文件读写。常用于嵌入式设备的固件升级、数据导出或作为虚拟光驱。
- 内核模块:
g_mass_storage.ko或通过 ConfigFS 配置mass_storage.usb - 后端存储: 可以是物理分区 (
/dev/sda1)、文件镜像 (file.bin) 或 RAM 盘 - 典型应用: 开发板模拟 U 盘、路由器共享存储
1.3.2 以太网 Gadget (Ethernet Gadget)
模拟 USB 网卡,通常使用 CDC ECM (Ethernet Control Model) 或 RNDIS (Microsoft 私有协议) 协议。Host 侧会枚举出一个虚拟网口,实现设备与 Host 之间的网络通信。
- 内核模块:
g_ether.ko(ECM) 或g_cdc.ko - IP 分配: 通常通过 DHCP 或静态 IP 配置,Host 端自动获取
- 典型应用: 开发板共享网络、ADB 调试、IoT 设备配置
1.3.3 串口 Gadget (Serial Gadget)
模拟 USB 转串口适配器,使用 CDC ACM (Abstract Control Model) 协议。Host 侧会创建一个虚拟串口 (如 /dev/ttyACM0),用于双向数据传输。
- 内核模块:
g_serial.ko或g_acm_ms.ko - 波特率: 虚拟串口通常忽略波特率设置,仅传输数据流
- 典型应用: 嵌入式控制台、Modem 通信、传感器数据采集
1.3.4 HID Gadget (Human Interface Device)
模拟键盘、鼠标、游戏手柄等输入设备。HID Gadget 可以发送按键事件、鼠标移动或自定义 HID 报告,用于自动化测试、远程控制或特殊输入场景。
- 内核模块:
g_hid.ko或通过 ConfigFS 配置hid.usb - 报告描述符: 需要自定义 HID Report Descriptor 定义数据格式
- 典型应用: 自动化按键注入、KVM 切换器、特殊工业控制器
1.4 Gadget 配置方式演进
Linux 内核中 Gadget 的配置方式经历了从旧式模块参数到现代 ConfigFS 的演进。了解这些方式有助于阅读内核日志和定位配置问题。
| 配置方式 | 内核版本 | 特点 | 示例 |
|---|---|---|---|
| Legacy Module Params | 2.6.x ~ 3.x | 通过模块参数加载,功能固定 | modprobe g_mass_storage file=/data.img |
| GadgetFS | 2.6.x ~ 4.x | 用户态文件系统接口,灵活但复杂 | 挂载 gadgetfs 后手动写描述符 |
| ConfigFS (推荐) | 3.11+ | 基于 sysfs 的配置,支持复合设备 | 通过 /sys/kernel/config/usb_gadget/ 配置 |