3. 开发环境准备:硬件选型与工具链搭建
USB Gadget 驱动开发依赖硬件平台提供 USB Device 控制器(UDC),并需要交叉编译工具链将内核与驱动编译为目标架构。本节从硬件选型、工具链安装、内核源码获取三个维度,搭建一套可复现的调试环境。
3.1 硬件平台选型对比
主流 USB Gadget 开发板为 BeagleBone Black 和 Raspberry Pi Zero,两者均内置 USB Device 控制器,但硬件规格与调试便利性存在差异。
| 对比项 | BeagleBone Black (Rev C) | Raspberry Pi Zero (W) |
|---|---|---|
| SoC | AM3358 (ARM Cortex-A8) | BCM2835 (ARM1176JZF-S) |
| 主频 | 1 GHz | 1 GHz |
| RAM | 512 MB DDR3 | 512 MB SDRAM |
| USB Device 控制器 | MUSB (Dual-Role) | DWC2 (Dual-Role) |
| USB 端口 | 1x USB Host + 1x USB Device (mini-USB) | 1x micro-USB (OTG) |
| 调试串口 | 板载 FTDI (6-pin 排针) | 需外接 UART 转 USB |
| 存储 | 4 GB eMMC + microSD | microSD |
| GPIO/扩展 | 92 个 GPIO, 7 个 ADC | 26 个 GPIO |
| 社区驱动支持 | 主线内核支持完善 | 主线内核支持完善 |
| 价格(参考) | 约 ¥350 | 约 ¥80 |
选型建议: 初学者推荐 BeagleBone Black,因其板载调试串口、eMMC 存储和丰富的 GPIO,可减少外围硬件搭建成本。Raspberry Pi Zero 适合预算有限或需要极小尺寸嵌入的场景,但需额外准备 UART 调试线。
3.2 硬件连接与调试拓扑
开发主机(x86_64 Linux)通过 USB 转串口线连接目标板的调试串口,同时目标板通过 USB Device 端口连接开发主机(或 USB 分析仪)。下图展示典型调试拓扑:
连接要点:
- 目标板 USB Device 端口(BeagleBone Black 为 P2 mini-USB,Pi Zero 为 micro-USB OTG)直连开发主机 USB Host。
- 串口调试线连接目标板 UART0(BeagleBone Black 为 J1 排针,Pi Zero 需焊接排针或使用 GPIO 14/15)。
- USB 分析仪(如 Beagle USB 480 Pro)串接在 USB 线路上,用于抓取 USB 描述符与控制传输。
3.3 交叉编译工具链安装
目标板为 ARM 架构,开发主机为 x86_64,必须使用交叉编译工具链。推荐两种方式:
3.3.1 使用 Linaro GCC(通用 ARM 工具链)
# 下载 Linaro ARM 工具链(7.5-2019.12 版本,支持 ARMv7-A 和 ARMv6)
wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
# 解压到 /opt 目录
sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt
# 添加至 PATH(建议写入 ~/.bashrc)
export PATH=/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin:$PATH
# 验证安装
arm-linux-gnueabihf-gcc --version
3.3.2 使用 Buildroot 构建定制工具链(推荐)
Buildroot 可生成与内核版本匹配的完整工具链,避免 glibc 版本冲突:
# 克隆 Buildroot 2024.02 LTS
git clone https://git.busybox.net/buildroot -b 2024.02.x
cd buildroot
# 配置目标架构(以 BeagleBone Black 为例)
make beaglebone_defconfig
# 定制工具链(仅生成工具链,不构建根文件系统)
make toolchain
# 工具链输出路径:output/host/bin/
export PATH=$PWD/output/host/bin:$PATH
arm-linux-gcc --version
注意: 如果使用 Raspberry Pi Zero(ARMv6 架构),需在 Buildroot 配置中选择
BR2_arm1176jzf_s 或使用 raspberrypi0_defconfig。Linaro 工具链默认针对 ARMv7-A,编译 ARMv6 代码时需添加 -march=armv6 标志。
3.4 内核源码获取与配置
USB Gadget 驱动开发需要获取 Linux 内核主线源码,并针对目标板进行配置。
3.4.1 获取内核源码
# 克隆主线内核(推荐 v6.6 LTS,长期支持)
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git -b v6.6
cd linux
# 查看当前分支
git branch -a
3.4.2 配置内核(以 BeagleBone Black 为例)
# 使用默认配置
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- omap2plus_defconfig
# 手动调整 USB Gadget 相关选项
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
# 必须启用的选项(在 menuconfig 中搜索并设置 =y 或 =m):
# Device Drivers --->
# [*] USB support --->
# <*> USB Gadget Support --->
# <*> USB Gadget Functions (usb_f_*)
# <*> USB Gadget Drivers (g_serial, g_ether, g_mass_storage, etc.)
# [*] Debugging files for USB Gadget
# <*> MUSB HDRC support --->
# [*] Support for Mentor USB OTG controller (AM335x)
3.4.3 编译内核与设备树
# 编译内核镜像
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j$(nproc) zImage
# 编译设备树
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j$(nproc) dtbs
# 编译内核模块
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j$(nproc) modules
# 输出文件位置:
# arch/arm/boot/zImage —— 内核镜像
# arch/arm/boot/dts/am335x-boneblack.dtb —— 设备树
3.5 内核 USB Gadget 配置结构
USB Gadget 子系统在内核中的配置层次如下:
配置要点:
- UDC 驱动:必须与目标板 SoC 匹配(BeagleBone Black 选 MUSB,Pi Zero 选 DWC2)。
- 功能驱动:实现具体 USB 功能(串口、以太网、存储等),编译为模块可动态加载。
- 协议驱动:组合多个功能驱动形成完整 USB 设备(如 g_serial 仅串口,g_ether 仅网卡)。
- ConfigFS:推荐使用,通过 sysfs 动态创建/销毁 Gadget,无需重新编译内核。
3.6 环境验证清单
完成上述步骤后,执行以下检查确认环境就绪:
| 检查项 | 验证命令 | 预期结果 |
|---|---|---|
| 交叉编译器可用 | arm-linux-gnueabihf-gcc --version | 显示版本号,无错误 |
| 内核源码完整 | git log --oneline -1 | 显示最新提交哈希 |
| 内核配置正确 | grep CONFIG_USB_GADGET .config | =y 或 =m |
| 编译输出存在 | ls -l arch/arm/boot/zImage | 文件存在,大小合理 |
| 设备树文件存在 | ls -l arch/arm/boot/dts/am335x-boneblack.dtb | 文件存在 |
| 串口调试连通 | screen /dev/ttyUSB0 115200 | 目标板启动日志输出 |
下一步: 环境准备完成后,第 4 章将演示如何编写第一个 USB Gadget 驱动——USB 串口设备(g_serial),并验证主机端枚举与数据收发。