Android USB / FunctionFS

FunctionFS 只有 ep0,没有 ep1 / ep2:正确的排查顺序

这个问题通常不是“内核没有创建端点”这么简单。需要先验证用户态描述符写入,再检查 Daemon 生命周期、SELinux、ConfigFS 和 USB Gadget HAL 时序。

FunctionFSep0ConfigFSUSB GadgetAndroid Vendor

ep0 存在并不代表 FunctionFS 已准备完成

ep0 是 FunctionFS 控制端点入口。用户态 Daemon 需要打开 ep0 并写入有效的 Descriptors 与 Strings,内核才会根据描述符创建后续数据端点。只看到 ep0 时,优先检查描述符写入,而不是先修改 ConfigFS 链接。

排查顺序

  1. 确认 FunctionFS 已挂载到预期路径,Daemon 打开的就是同一个 mount。
  2. 检查 ep0 open 和 descriptor write 的返回值、长度及 errno。
  3. 核对描述符版本、结构长度、Interface、Endpoint 数量、方向和最大包长。
  4. 确认 Daemon 写完描述符后没有退出,SELinux 没有阻止后续访问。
  5. 最后检查 ConfigFS function、configuration symlink、UDC 与 Gadget HAL 状态。

常见错误

写入结构长度错误

代码编译通过,但内核拒绝描述符,端点不会生成。必须记录实际 write 返回值。

使用旧 fd

经历 UNBIND / 重连后仍使用旧端点 fd,导致初始化看似成功但无法通信。

Daemon 提前退出

init 自动重启造成 ep0 反复创建,容易误判为 ConfigFS 问题。

SELinux / DAC

目录可见不代表允许 open、write 和 ioctl,需同时检查 ls -Z 与 AVC。

验证标准

  • 写入描述符后数据端点稳定出现。
  • UDC 绑定后主机能完成枚举和 SET_CONFIGURATION。
  • Daemon 能在 Bulk IN / OUT 上稳定读写。
  • 拔插、USB Reset、Suspend / Resume 后可重新初始化。