RK3588 kernel-6.1:drivers/usb/mon 功能与实现要点
源码基准:rk3588/kernel-6.1/drivers/usb/mon/。内核文档:Documentation/usb/usbmon.rst(Kconfig 中亦有指向)。
1. 驱动定位(USB Monitor / usbmon)
CONFIG_USB_MON 编译为 usbmon.ko(或内置 usbmon.o),实现 USB 流量窥探:在 urb 提交、提交失败、完成回调 等关键点抓取事件,供 debugfs(及部分二进制字符接口)读出。
观测边界:钩子插在 drivers/usb/core/hcd.c 的 usb_hcd_submit_urb / usb_hcd_giveback_urb(近似路径)上,因此捕获的是 主机控制器栈上的 URB(设备侧驱动 ↔ HCD)。Gadget 侧 usb_request 不走这套 usbmon_urb_* 钩子(仓库内仅 hcd.c 调用 usbmon_urb_*)。
2. 文件分工
| 文件 | 职责 |
|---|---|
mon_main.c |
模块 init/exit;usb_mon_register 向 usbcore 注册 usb_mon_operations;USB_BUS_ADD/USB_BUS_REMOVE notifier;struct mon_bus 与 usb_bus 绑定;mon_reader_* 管理读者并开关 usb_bus->monitored |
mon_text.c |
文本格式 trace:debugfs 下可按总线打开;事件 mon_event_text;载荷 DATA_MAX=32 字节封顶(大块应用二进制接口) |
mon_bin.c |
二进制格式:环形缓冲、ioctl(MON_IOC_*)、可携带更长 payload;mon_bin_hdr 用户可见布局 |
mon_stat.c |
0s 类统计:读者数、事件计数、text_lost(根权限,注释说明) |
usb_mon.h |
mon_bus/mon_reader 回调原型 rnf_submit/rnf_error/rnf_complete |
3. 与 usbcore 的衔接(实现原理)
3.1 注册与 hot path 门槛
include/linux/usb/hcd.h(在 CONFIG_USB_MON 时)定义 struct usb_mon_operations 及 usbmon_urb_submit/usbmon_urb_submit_error/usbmon_urb_complete:
- 仅当
bus->monitored != 0时才调用mon_ops->...,避免无监听时的开销。 usb_mon_register在hcd.c末尾实现:全局mon_ops指针,带mb(),故意 不在热路径持锁。
3.2 HCD 调用点
hcd.c 在 usb_hcd_submit_urb 里:DMA map / urb_enqueue 之前 调 usbmon_urb_submit;若 urb_enqueue 失败 则 usbmon_urb_submit_error。在 usb_hcd_giveback_urb(完成路径)调 usbmon_urb_complete。
3.3 何时 monitored == 1
mon_main.c:
- 每个
usb_bus在mon_bus_init(NotifierUSB_BUS_ADD或模块加载时遍历已有总线)里分配mon_bus,并mon_text_add/mon_bin_add创建 debugfs 节点。 mon_bus0:逻辑「所有总线」;有读者打开mon_bus0时,list_for_each把所有已知usb_bus->monitored置 1。- 针对某一
usbN的mon_bus:该总线第一个读者到来时monitored = 1;最后一个读者离开mon_stop清 0。
事件分发:mon_submit 先发到 ubus->mon_bus 上的读者,再发到 mon_bus0 上的读者(全局监听重复收到同一条 URB 属于设计)。
4. 文本与二进制接口要点
- 文本:适合人工阅读;setup 最多 8 字节;数据快照 有意限制长度以防用户态不读导致内核积压(仍有
EVENT_MAX与cnt_text_lost统计丢事件)。 - 二进制:
CHUNK_SIZE页对齐块、默认/最大缓冲BUFF_DFL/BUFF_MAX;MON_IOCX_GET/MFETCH等批量取事件;适合抓 Bulk 等大数据。 - 统计:
mon_stat.c读取mon_bus的nreaders/cnt_events/cnt_text_lost。
实际挂载路径与节点命名以实现为准(常见在 /sys/kernel/debug/usbmon);权限模型依赖 debugfs 与内核 DAC,文档强调需特权以防嗅探 HID 密码等。
5. 小结
| 项目 | 说明 |
|---|---|
| 抓什么 | 主机侧 urb:submit / submit-fail / complete |
| 不抓什么 | Gadget 栈(无对应钩子) |
| 开关 | usb_bus.monitored + mon_ops 非空 |
| 扩展 | 新读者实现 mon_reader 三套 rnf_* 即可接入 mon_bus |
调试 RK3588 主机 USB 枚举与传输时,若已启用 USB_MON,可配合 usbmon.rst 与用户态 cat/`Wireshark**(pcap)流程分析 URB 时间线。
正在加载留言…