USB Raw Gadget
USB Raw Gadget 是一个小工具驱动程序,可让用户空间对小工具的通信过程进行低级控制。
与任何其他小工具驱动程序一样,Raw Gadget 通过 USB 小工具 API 实现 USB 设备。 与大多数小工具驱动程序不同,Raw Gadget 本身不实现任何具体的 USB 功能,但需要用户空间来执行此操作。
Raw Gadget 目前是一个严格的调试功能,不应在生产中使用。 请改用 GadgetFS。
通过 CONFIG_USB_RAW_GADGET 启用。
1. Comparison to GadgetFS
Raw Gadget 与 GadgetFS 类似,但为用户空间提供了对 USB gadget 层的更直接的访问。 主要区别是:
- Raw Gadget 将每个 USB 请求传递到用户空间以获得响应,而 GadgetFS 根据提供的描述符在内部响应某些 USB 请求。 请注意,UDC 驱动程序可能会自行响应某些请求,并且从不将它们转发到小工具层。
- Raw Gadget 允许提供任意数据作为对 USB 请求的响应,而 GadgetFS 对提供的 USB 描述符执行健全性检查。 这使得 Raw Gadget 适合通过提供格式错误的数据作为对 USB 请求的响应来进行模糊测试。
- Raw Gadget 提供了一种选择要绑定的 UDC 设备/驱动程序的方法,而 GadgetFS 当前绑定到第一个可用的 UDC。 这允许将多个原始小工具实例绑定到不同的 UDC。
- 原始小工具显式公开有关端点地址和功能的信息。 这允许用户编写与 UDC 无关的小工具。
- Raw Gadget 有一个基于 ioctl 的接口,而不是基于文件系统的接口。
2. Userspace interface
用户可以通过打开 /dev/raw-gadget 并发出 ioctl 调用来与 Raw Gadget 进行交互; 有关详细信息,请参阅 include/uapi/linux/usb/raw_gadget.h 中的注释。 可以同时使用多个Raw Gadget实例(绑定到不同的UDC)。
Raw Gadget的典型使用场景:
- 通过打开 /dev/raw-gadget 创建一个 Raw Gadget 实例。
- 通过 USB_RAW_IOCTL_INIT 初始化实例。
- 使用 USB_RAW_IOCTL_RUN 启动实例。
- 在循环中发出 USB_RAW_IOCTL_EVENT_FETCH 以接收来自原始小工具的事件,并根据必须实现哪种 USB 小工具对这些事件做出反应。
请注意,某些 UDC 驱动程序具有分配给端点的固定地址,因此不能在描述符中使用任意端点地址。 尽管如此,Raw Gadget 提供了一种与 UDC 无关的方式来编写 USB 小工具。 通过 USB_RAW_IOCTL_EVENT_FETCH 接收到 USB_RAW_EVENT_CONNECT 后,USB_RAW_IOCTL_EPS_INFO 可用于查找有关 UDC 驱动程序具有的端点的信息。 基于此,用户空间必须为小工具选择 UDC 端点,并相应地在端点描述符中分配地址。
原始小工具使用示例和测试套件:
https://github.com/xairy/raw-gadget
3. Internal details
每个原始小工具端点读/写 ioctl 都会提交 USB 请求并等待其完成。 这样做是有意为之,通过让单个系统调用完全处理单个 USB 请求来协助覆盖引导的模糊测试。 在实现中必须保留此功能。
4. Potential future improvements
支持 O_NONBLOCK I/O。 这将是另一种操作模式,其中 Raw Gadget 不会等到每个 USB 请求完成。
支持 USB 3 功能(启用端点时接受 SS 端点伴随描述符;允许为批量传输提供stream_id)。
支持 ISO 传输功能(公开已完成请求的帧号)。