USB Gadget 子系统详解:OTG 口模拟各类 USB 外设
1. 前言
很多开发者在使用 LubanCat 开发板时,会注意到板子上有一个 OTG(On-The-Go)口。这个口不仅仅是用来烧录固件或连接 USB 设备的——它还有一个非常强大的能力:让开发板模拟成各种 USB 外设,被 PC 或其他 USB Host 识别。
重要前提:只有 OTG 口才能模拟 USB 外设,普通 USB-A 口不行。 原因在于硬件层面——USB 控制器分为 Host-only 和 Dual-Role(OTG)两种,普通 USB-A 口背后的 EHCI/xHCI 控制器只支持 Host 模式,硬件上没有 Device 模式的端点和寄存器;只有 OTG 口背后的 DWC3 控制器支持双角色切换,才能加载 Gadget 驱动模拟外设。详见下方 第 8 节 的设备树分析。
本文将深度剖析 kernel-6.1/drivers/usb/gadget/ 目录的完整结构,详细介绍 Linux 内核提供的所有 USB Gadget 功能,让你了解开发板到底能模拟哪些 USB 设备。
2. 什么是 USB Gadget?
2.1 USB 的两种角色
USB 协议中定义了两种角色:
| 角色 | 说明 | 硬件接口 | 典型设备 |
|---|---|---|---|
| USB Host | 主控端,发起所有通信 | Type-A 口 | PC、手机(OTG模式下) |
| USB Device/Gadget | 从设备,响应 Host 请求 | Type-B / Micro-B / Type-C | U盘、摄像头、键盘 |
USB Gadget 就是让 Linux 设备充当 USB Device 角色的框架。 通过 OTG 口,开发板可以在 Host 和 Device 两种角色之间切换。
2.2 Gadget 框架的三层架构
┌─────────────────────────────────────────────────────────────────┐
│ 用户空间 / configfs 配置层 │
│ /config/usb_gadget/g1/functions/... │
├─────────────────────────────────────────────────────────────────┤
│ Function 层(可模拟的 USB 设备类型) │
│ f_mass_storage / f_hid / f_uvc / f_acm / f_rndis / ... │
├─────────────────────────────────────────────────────────────────┤
│ Composite 框架层(组合多个 Function) │
│ composite.c / configfs.c / epautoconf.c │
├─────────────────────────────────────────────────────────────────┤
│ UDC 层(USB Device Controller 硬件驱动) │
│ dwc3 / dwc2 / fsl_udc / ... │
├─────────────────────────────────────────────────────────────────┤
│ USB 硬件控制器 (DWC3 on RK3588) │
└─────────────────────────────────────────────────────────────────┘
3. 目录结构总览
源码位置:kernel-6.1/drivers/usb/gadget/
drivers/usb/gadget/
├── composite.c ← Composite 框架核心(组合多个 Function)
├── config.c ← USB Configuration 管理
├── configfs.c ← configfs 接口(用户空间配置 Gadget)
├── configfs.h
├── epautoconf.c ← 端点自动配置
├── functions.c ← Function 注册管理
├── u_f.c / u_f.h ← 通用工具函数
├── u_os_desc.h ← OS 描述符支持
├── usbstring.c ← USB 字符串描述符处理
├── Kconfig ← 内核配置选项
├── Makefile
│
├── function/ ← ★ Function 驱动(每种模拟设备一个)★
│ ├── f_mass_storage.c → U盘
│ ├── f_hid.c → 键盘/鼠标
│ ├── f_uvc.c → USB 摄像头
│ ├── f_acm.c → 虚拟串口
│ ├── f_rndis.c → Windows 网卡
│ ├── f_ecm.c → Linux/Mac 网卡
│ ├── f_ncm.c → 高速网卡
│ ├── f_uac1.c → USB 音频 1.0
│ ├── f_uac2.c → USB 音频 2.0
│ ├── f_midi.c → MIDI 乐器
│ ├── f_printer.c → USB 打印机
│ ├── f_serial.c → 通用串口
│ ├── f_eem.c → 简化网卡
│ ├── f_subset.c → 最简网卡
│ ├── f_obex.c → OBEX 交换
│ ├── f_phonet.c → Nokia 电话协议
│ ├── f_fs.c → FunctionFS(用户空间自定义)
│ ├── f_loopback.c → 回环测试
│ ├── f_sourcesink.c → 源/汇测试
│ └── f_tcm.c → SCSI 存储目标
│
├── legacy/ ← 预组合的完整 Gadget 驱动
│ ├── mass_storage.c → g_mass_storage(纯U盘)
│ ├── ether.c → g_ether(纯网卡)
│ ├── serial.c → g_serial(纯串口)
│ ├── hid.c → g_hid(纯HID)
│ ├── audio.c → g_audio(纯音频)
│ ├── webcam.c → g_webcam(纯摄像头)
│ ├── printer.c → g_printer(纯打印机)
│ ├── midi.c → g_midi(纯MIDI)
│ ├── multi.c → g_multi(多功能组合)
│ ├── acm_ms.c → g_acm_ms(串口+U盘)
│ ├── ncm.c → g_ncm(NCM网卡)
│ ├── zero.c → g_zero(测试用)
│ ├── raw_gadget.c → raw_gadget(底层测试)
│ └── ...
│
└── udc/ ← USB Device Controller 硬件驱动
├── core.c → UDC 核心框架
├── ...(各平台 UDC 驱动)
└── dummy_hcd.c → 虚拟 HCD(测试用)
4. 可模拟的 USB 设备类型详解
4.1 USB 存储类(Mass Storage)
模拟设备: U盘、移动硬盘、光驱
原理: 将开发板上的一个文件或块设备(如 SD 卡分区、eMMC 分区)通过 USB Mass Storage 协议暴露给 Host,Host 会将其识别为一个可移动磁盘。
Kconfig: CONFIG_USB_F_MASS_STORAGE
典型用途:
- 将开发板的 SD 卡共享给 PC 访问
- 制作 USB 启动盘
- 嵌入式设备固件升级(将固件分区暴露为U盘)
# 示例:将 /dev/mmcblk1p1 共享为 U盘
echo /dev/mmcblk1p1 > /config/usb_gadget/g1/functions/mass_storage.0/lun.0/file
还有一个更高级的存储 Gadget:f_tcm.c,基于 Linux 内核的 TCM(Target Core Module)框架,支持 UAS(USB Attached SCSI)协议,性能更好,支持 USB 3.0 流。
4.2 USB 人机接口类(HID)
源码: function/f_hid.c
模拟设备: USB 键盘、USB 鼠标、USB 游戏手柄、USB 触摸屏
原理: HID 是 USB 协议中最简单的设备类之一。Gadget 端注册一个 /dev/hidgX 设备节点,用户空间向其写入 HID 报告描述符对应的数据,Host 就会将其解释为键盘按键、鼠标移动等。
Kconfig: CONFIG_USB_F_HID
典型用途:
- 开发板模拟键盘自动输入字符
- 开发板模拟鼠标控制 PC
- 自定义 HID 设备(如 USB 按钮、旋钮)
- BadUSB 安全研究
# 示例:模拟键盘,向 Host 发送 "Hello"
echo -n "Hello" > /dev/hidg0
4.3 USB 摄像头类(UVC)
源码: function/f_uvc.c
模拟设备: USB 摄像头/网络摄像头
原理: 通过 UVC(USB Video Class)协议,将开发板采集的视频帧通过 USB 发送给 Host。Host 端的 UVC 驱动会自动识别,创建 /dev/videoX 节点。详见 0204 文档。
Kconfig: CONFIG_USB_F_UVC
典型用途:
- 将 MIPI CSI 摄像头的画面通过 USB 传给 PC
- 将开发板屏幕内容作为 USB 摄像头输出
- 远程监控/视频会议
- 机器视觉系统(开发板处理图像后通过 UVC 输出)
4.4 USB 串口类(CDC ACM / Serial)
源码: function/f_acm.c、function/f_serial.c
模拟设备: USB 虚拟串口(COM 口)
原理: CDC ACM(Abstract Control Model)是 USB 通信设备类的一种,模拟标准串口。Host 端会加载 cdc-acm 驱动,创建 /dev/ttyACMx 设备节点。
Kconfig: CONFIG_USB_F_ACM、CONFIG_USB_F_SERIAL
两者区别:
| 特性 | f_acm (CDC ACM) | f_serial (Generic Serial) |
|---|---|---|
| 协议 | 标准 CDC ACM | 简单 Bulk 传输 |
| Host 驱动 | cdc-acm(系统自带) | 需要专用驱动 |
| 控制信号 | 支持 DTR/RTS/CTS 等 | 无 |
| 兼容性 | Windows/Linux/Mac 通用 | 仅 Linux |
典型用途:
- 开发板通过 USB 给 PC 提供串口控制台
- 两个 Linux 设备之间通过 USB 串口通信
- 嵌入式设备固件调试
4.5 USB 网络类(RNDIS / ECM / NCM / EEM)
这是最复杂的一类,有多种协议可选:
4.5.1 RNDIS(Remote NDIS)
模拟设备: USB 网卡(Windows 兼容)
Kconfig: CONFIG_USB_F_RNDIS
特点: 微软私有协议,Windows XP 及以上系统原生支持,无需安装驱动。是与 Windows 通信的首选。
4.5.2 CDC ECM(Ethernet Control Model)
源码: function/f_ecm.c
模拟设备: USB 网卡(Linux/Mac 兼容)
Kconfig: CONFIG_USB_F_ECM
特点: 标准 CDC 协议,Linux 和 macOS 原生支持,Windows 不支持。
4.5.3 CDC NCM(Network Control Model)
源码: function/f_ncm.c
模拟设备: 高速 USB 网卡
Kconfig: CONFIG_USB_F_NCM
特点: ECM 的升级版,支持将多个以太网帧打包到一个 USB 传输中,性能最好。4G/5G 模块常用此协议。
4.5.4 CDC EEM(Ethernet Emulation Model)
源码: function/f_eem.c
模拟设备: 简化 USB 网卡
Kconfig: CONFIG_USB_F_EEM
特点: 比 ECM 更简单,对硬件要求更低。
4.5.5 CDC Subset(最小以太网)
模拟设备: 最简 USB 网卡
Kconfig: CONFIG_USB_F_SUBSET
特点: 最精简的以太网实现,适用于硬件能力有限的控制器。
网络类协议对比:
| 协议 | Windows | Linux | macOS | 性能 | 复杂度 |
|---|---|---|---|---|---|
| RNDIS | 原生支持 | 需 rndis_host | 不支持 | 中 | 中 |
| ECM | 不支持 | 原生支持 | 原生支持 | 中 | 低 |
| NCM | Win10+ | 原生支持 | 原生支持 | 高 | 高 |
| EEM | 不支持 | 原生支持 | 不支持 | 中 | 低 |
| Subset | 不支持 | 原生支持 | 不支持 | 低 | 最低 |
典型用途:
- 开发板通过 USB 共享网络给 PC(USB 网络共享)
- 开发板通过 USB 连接 PC 进行 SSH/FTP 等网络操作
- Android 手机的 USB 网络共享(USB Tethering)
4.6 USB 音频类(UAC 1.0 / 2.0)
源码: function/f_uac1.c、function/f_uac2.c
模拟设备: USB 声卡/USB 音频设备
Kconfig: CONFIG_USB_F_UAC1、CONFIG_USB_F_UAC2
两者区别:
| 特性 | UAC 1.0 (f_uac1) | UAC 2.0 (f_uac2) |
|---|---|---|
| 最大采样率 | 96kHz | 384kHz |
| 最大位深 | 24-bit | 32-bit |
| 通道数 | 有限 | 更多 |
| 虚拟 ALSA 声卡 | 是 | 是 |
| 需要硬件 codec | 否(虚拟) | 否(虚拟) |
另外还有一个 f_uac1_legacy.c,它需要真实的音频编解码器硬件配合。
典型用途:
- 开发板作为 USB 声卡,PC 通过它播放/录制音频
- USB 音频流传输
- 专业音频设备
4.7 USB MIDI 类
模拟设备: USB MIDI 乐器/控制器
Kconfig: CONFIG_USB_F_MIDI
典型用途:
- 开发板模拟 MIDI 键盘/控制器
- 连接音乐制作软件
- MIDI 信号路由/转换
4.8 USB 打印机类
模拟设备: USB 打印机
Kconfig: CONFIG_USB_F_PRINTER
原理: 注册 /dev/g_printerX 设备节点,Host 发送的打印数据会写入该节点,用户空间程序读取并处理。
典型用途:
- 模拟 USB 打印机接收打印任务
- 测试 Host 端打印机驱动
- 打印任务拦截/转发
4.9 USB OBEX 类
模拟设备: OBEX 文件交换设备
Kconfig: CONFIG_USB_F_OBEX
典型用途:
- 类似蓝牙 OBEX 的文件传输
- 手机与 PC 之间的文件交换
4.10 USB Phonet 类
模拟设备: Nokia Phonet 蜂窝调制解调器
Kconfig: CONFIG_USB_F_PHONET
说明: 专用于 Nokia N900 等老款手机的蜂窝调制解调器通信协议,目前很少使用。
4.11 FunctionFS(用户空间自定义)
源码: function/f_fs.c
模拟设备: 任意 USB 设备(由用户空间定义)
Kconfig: CONFIG_USB_F_FS
原理: FunctionFS 提供了一个文件系统接口(/dev/usb-ffs/),允许用户空间程序直接实现 USB 设备的描述符和数据处理逻辑,无需编写内核驱动。
典型用途:
- Android ADB(Android Debug Bridge)
- MTP(Media Transfer Protocol,媒体传输协议)
- 任何需要在用户空间实现的 USB 协议
# FunctionFS 目录结构
/dev/usb-ffs/adb/
├── ep0 ← 控制端点(描述符读写)
├── ep1 ← Bulk IN 端点
└── ep2 ← Bulk OUT 端点
4.12 测试用 Gadget
Gadget Zero(回环/源汇测试)
源码: function/f_loopback.c、function/f_sourcesink.c
用途: 用于测试 USB 控制器硬件和驱动的正确性。Host 端使用 usbtest 驱动配合测试。
f_loopback.c:将收到的数据原样回传(Loopback)f_sourcesink.c:一端产生数据(Source),另一端消耗数据(Sink)
Raw Gadget
用途: 提供最底层的 USB Gadget 访问接口,允许用户空间完全控制 USB 通信过程。用于 USB 协议安全研究、Fuzzing 测试。
5. Legacy 预组合 Gadget 驱动
legacy/ 目录下的驱动是将多个 Function 组合在一起的"开箱即用"方案:
| 模块名 | 源码 | 组合内容 | 用途 |
|---|---|---|---|
g_mass_storage | mass_storage.c | Mass Storage | 纯 U盘 |
g_ether | ether.c | RNDIS + ECM + EEM + Subset | 纯网卡 |
g_serial | serial.c | ACM + Serial + OBEX | 纯串口 |
g_hid | hid.c | HID | 纯 HID 设备 |
g_audio | audio.c | UAC 1.0/2.0 | 纯音频 |
g_webcam | webcam.c | UVC + UAC | 纯摄像头 |
g_printer | printer.c | Printer | 纯打印机 |
g_midi | gmidi.c | MIDI | 纯 MIDI |
g_ncm | ncm.c | NCM | NCM 网卡 |
g_multi | multi.c | RNDIS + ACM + Mass Storage | 多功能组合 |
g_acm_ms | acm_ms.c | ACM + Mass Storage | 串口+U盘 |
g_zero | zero.c | Loopback + SourceSink | 测试用 |
现代推荐: 使用 configfs 方式动态配置,而不是加载 legacy 模块。configfs 允许在运行时自由组合多个 Function,更灵活。
6. configfs 动态配置方式
6.1 基本流程
# 1. 挂载 configfs
mount -t configfs none /config
mkdir -p /config/usb_gadget/g1
# 2. 设置 USB VID/PID
echo 0x1d6b > /config/usb_gadget/g1/idVendor # Linux Foundation
echo 0x0104 > /config/usb_gadget/g1/idProduct # Multifunction Composite Gadget
# 3. 创建 Function 实例(可创建多个)
mkdir /config/usb_gadget/g1/functions/acm.usb0 # 串口
mkdir /config/usb_gadget/g1/functions/rndis.usb0 # 网卡
mkdir /config/usb_gadget/g1/functions/mass_storage.0 # U盘
# 4. 配置 U盘后端
echo /dev/mmcblk1p1 > /config/usb_gadget/g1/functions/mass_storage.0/lun.0/file
# 5. 创建 Configuration 并绑定 Function
mkdir /config/usb_gadget/g1/configs/c.1
ln -s /config/usb_gadget/g1/functions/acm.usb0 /config/usb_gadget/g1/configs/c.1/
ln -s /config/usb_gadget/g1/functions/rndis.usb0 /config/usb_gadget/g1/configs/c.1/
ln -s /config/usb_gadget/g1/functions/mass_storage.0 /config/usb_gadget/g1/configs/c.1/
# 6. 绑定到 UDC(USB Device Controller)
echo <udc_name> > /config/usb_gadget/g1/UDC
6.2 查看可用的 UDC
ls /sys/class/udc/
# RK3588 上通常显示:fe8a0000.usb 或类似名称
7. 与 RK3588 硬件的关系
RK3588 芯片内部集成了 DesignWare DWC3 USB 3.0 控制器,支持 Host/Device/OTG 三种模式。Linux 内核中对应的驱动在 drivers/usb/dwc3/ 目录下。
RK3588 USB OTG 口
│
├── 硬件:DWC3 USB 3.0 控制器
│
├── 内核驱动:drivers/usb/dwc3/
│
├── Gadget 框架:drivers/usb/gadget/
│ ├── composite.c → 组合框架
│ ├── function/ → 各种 Function 驱动
│ └── configfs.c → 用户空间配置接口
│
└── 用户空间工具:
├── configfs 直接配置
├── libusbgx(USB Gadget 扩展库)
└── gt(Gadget 工具)
8. LubanCat 设备树中的 OTG 配置分析
8.1 RK3588/RK3588S 的 USB 控制器全貌
通过分析设备树源码,RK3588 芯片共有 4 个 USB 控制器,但只有 2 个 DWC3 控制器支持 OTG/Device 模式:
| 控制器 | 设备树节点 | 类型 | dr_mode | 支持 Gadget | 用途 |
|---|---|---|---|---|---|
| DWC3_0 | usbdrd_dwc3_0 | DWC3 | otg | 是 | OTG 口(Type-C) |
| DWC3_1 | usbdrd_dwc3_1 | DWC3 | host | 否(默认) | USB 3.0 Type-A 口 |
| EHCI_0/OHCI_0 | usb_host0 | EHCI/OHCI | host | 否 | USB 2.0 Type-A 口 |
| EHCI_1/OHCI_1 | usb_host1 | EHCI/OHCI | host | 否 | USB 2.0 Type-A 口 |
关键区别:
- DWC3 控制器(
snps,dwc3):支持 Host/Device/OTG 三种模式,通过dr_mode属性切换 - EHCI/OHCI 控制器:硬件上只支持 Host 模式,无法用于 Gadget
8.2 基础 dtsi 中的默认配置
在 rk3588s.dtsi:2577 中,DWC3_0 的默认配置:
usbdrd_dwc3_0: usb@fc000000 {
compatible = "snps,dwc3";
dr_mode = "otg"; ← 默认为 OTG 模式
phys = <&u2phy0_otg>, <&usbdp_phy0_u3>;
phy-names = "usb2-phy", "usb3-phy";
status = "disabled"; ← 默认禁用,需要板级 DTS 启用
};
在 rk3588.dtsi:102 中,DWC3_1 的默认配置:
usbdrd_dwc3_1: usb@fc400000 {
compatible = "snps,dwc3";
dr_mode = "host"; ← 默认为 Host 模式
phys = <&u2phy1_otg>, <&usbdp_phy1_u3>;
status = "disabled";
};
8.3 LubanCat 各板型的 OTG 启用情况
分析各板型 DTS 文件中对 usbdrd_dwc3_0 的配置:
| 板型 | DTS 文件 | DWC3_0 dr_mode | OTG 启用 |
|---|---|---|---|
| LubanCat 4 | rk3588s-lubancat-4.dts:1368 | otg | 是 |
| LubanCat 4IO | rk3588s-lubancat-4io.dts:1477 | otg | 是 |
| LubanCat 5 | rk3588-lubancat-5.dts:1385 | otg | 是 |
| LubanCat 5IO | rk3588-lubancat-5io.dts:1411 | otg | 是 |
| LubanCat 5IOI | rk3588-lubancat-5ioi.dts | otg | 是 |
| LubanCat 5-v2 | rk3588-lubancat-5-v2.dts | otg | 是 |
| generic | rk3588-lubancat-generic.dts | 未配置 | 否(需手动启用) |
以 rk3588s-lubancat-4io.dts:1472 为例:
/* USB3.0 OTG0 Controller */
&usbdrd3_0 {
status = "okay"; ← 启用 DWC3_0 控制器
};
&usbdrd_dwc3_0 {
dr_mode = "otg"; ← 设置为 OTG 模式
usb-role-switch; ← 启用角色自动切换
status = "okay";
port {
dwc3_0_role_switch: endpoint@0 {
remote-endpoint = <&usbc0_role_sw>; ← 连接 Type-C 控制器
};
};
};
8.4 LubanCat 的 USB 接口总结
LubanCat 开发板(以 LubanCat 4IO 为例)
│
├── USB 3.0 Type-C 口(OTG)
│ ├── 控制器:DWC3_0 (usbdrd_dwc3_0)
│ ├── dr_mode = "otg"
│ ├── 支持 Host + Device 双角色
│ ├── ★ 可以加载 Gadget 驱动,模拟 USB 外设 ★
│ └── UDC 名称:通过 ls /sys/class/udc/ 查看
│
├── USB 3.0 Type-A 口
│ ├── 控制器:DWC3_1 (usbdrd_dwc3_1)
│ ├── dr_mode = "host"
│ └── 仅支持 Host(接U盘/摄像头等)
│
└── USB 2.0 Type-A 口(如有)
├── 控制器:EHCI/OHCI
└── 仅支持 Host
结论:LubanCat 各板型只有 Type-C(OTG)口支持 Gadget 模式,可以模拟 USB 外设。其他 USB-A 口只能作为 Host 使用。
9. 总结
┌──────────────────────────────────────────────────────────────────┐
│ USB Gadget 可模拟的设备总览 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 存储类 │ f_mass_storage → U盘/移动硬盘/光驱 │
│ │ f_tcm → 高速 SCSI 存储(UAS) │
│ │
│ 人机接口 │ f_hid → 键盘/鼠标/游戏手柄/触摸屏 │
│ │
│ 视频类 │ f_uvc → USB 摄像头 │
│ │
│ 串口类 │ f_acm → CDC ACM 虚拟串口 │
│ │ f_serial → 通用串口 │
│ │
│ 网络类 │ f_rndis → Windows 网卡 │
│ │ f_ecm → Linux/Mac 网卡 │
│ │ f_ncm → 高速网卡(4G/5G) │
│ │ f_eem → 简化网卡 │
│ │ f_subset → 最简网卡 │
│ │
│ 音频类 │ f_uac1 → USB 音频 1.0 │
│ │ f_uac2 → USB 音频 2.0(高清) │
│ │ f_midi → MIDI 乐器接口 │
│ │
│ 打印类 │ f_printer → USB 打印机 │
│ │
│ 其他 │ f_fs → FunctionFS(用户空间自定义) │
│ │ f_obex → OBEX 文件交换 │
│ │ f_phonet → Nokia 蜂窝调制解调器 │
│ │ f_loopback → 回环测试 │
│ │ f_sourcesink → 源/汇测试 │
│ │
│ 总计:21 个 Function 驱动,12 个预组合 Legacy 驱动 │
└──────────────────────────────────────────────────────────────────┘
回答你的问题:是的,drivers/usb/gadget/ 目录就是专门用于让 USB OTG 口模拟各种 USB 外设的。 Linux 内核提供了 21 种 Function 驱动,可以模拟 U盘、网卡、摄像头、串口、声卡、键盘鼠标、打印机、MIDI 乐器等几乎所有标准 USB 设备类型。通过 configfs 还可以将多个 Function 组合在一起,让开发板同时模拟多种设备(如同时当 U盘 + 网卡 + 串口)。
但请注意:只有 OTG 口(Type-C)才能使用这些 Gadget 功能。 LubanCat 各板型的 Type-C 口背后是 DWC3 控制器,支持 dr_mode = "otg",可以切换为 Device 模式;而普通 USB-A 口背后的 EHCI/xHCI 控制器只支持 Host 模式,无法用于 Gadget。在使用前,请确认你的设备树中已正确启用 OTG 控制器(status = "okay" 且 dr_mode = "otg")。
10. 参考资料
- Linux 内核文档:Documentation/usb/gadget.rst
- USB Gadget API:Documentation/driver-api/usb/gadget.rst
- configfs Gadget 配置:Documentation/usb/gadget_configfs.rst
- LubanCat SDK 源码:kernel-6.1/drivers/usb/gadget/
- DWC3 控制器驱动:kernel-6.1/drivers/usb/dwc3/

4872

被折叠的 条评论
为什么被折叠?



