如何编写USB存储设备驱动:probe正常但fdisk -l无法识别设备的调试
核心问题根因
你使用的usb-skeleton是内核提供的通用USB字符设备占位模板,设计初衷是演示简单自定义USB外设的驱动匹配流程,本身不包含任何USB存储类设备的功能逻辑。它的probe函数能正常执行,仅仅是因为你修改了驱动的VID/PID匹配表,内核检测到ID匹配就触发了对应的probe回调,但这个驱动既没有实现USB存储协议的传输逻辑,也不会向上注册块设备节点,自然不会被fdisk识别到。
你之前执行的卸载usb_storage、uas模块、重命名原usb_storage.ko文件的操作,只是把系统原生的存储处理逻辑完全移除了,并没有补上对应的功能实现,空壳的skeleton驱动是不可能让存储设备正常工作的。
修复操作步骤
- 首先卸载你自行编译加载的skeleton自定义模块:执行
rmmod usb_skeleton,避免它抢占你的USB设备的匹配权限 - 把之前重命名的
usb_storage.ko恢复到对应内核版本的模块目录(一般为/lib/modules/$(uname -r)/kernel/drivers/usb/storage/),修正文件权限为644,执行depmod -a刷新模块依赖表 - 如果你的USB设备因为特殊VID/PID没有被原生
usb_storage的匹配表覆盖,不需要从零编写存储驱动,直接加载usb_storage模块时传入自定义ID参数即可:- 执行命令
modprobe usb_storage quirks=xxxx:xxxx,其中xxxx:xxxx替换为你设备实际的VID与PID - 或者直接把对应设备ID添加到内核源码
drivers/usb/storage/unusual_devs.h的匹配列表,重新编译usb_storage模块替换原文件即可
- 执行命令
- 加载完成后检查
/dev/sd*类设备节点是否生成,再执行fdisk -l验证识别结果
自定义开发场景的必备逻辑补充
如果你是出于学习目的,希望基于骨架代码实现可工作的USB存储设备驱动,仅修改VID/PID是完全不够的,必须补上以下核心功能:
- 实现USB存储类Bulk-Only Transport(BOT)协议的传输逻辑,完成与设备端的SCSI命令交互流程
- 对接内核SCSI中间层框架,向上注册SCSI磁盘设备
- 实现块设备的IO请求处理逻辑,对接内核块IO调度层
- 正确向udev上报设备信息,触发生成对应的块设备访问节点
验证排查要点
- 加载模块后执行
dmesg | tail -50,查看probe回调后的日志,如果没有块设备注册的相关输出,说明驱动本身没有实现块设备上报逻辑,不属于ID匹配故障 - 执行
lsblk检查系统当前块设备列表,确认是否存在对应USB存储设备的节点信息
内容的提问来源于stack exchange,提问作者user14102520
相关产品推荐
相关产品推荐

