Linux下USB MASS STORAGE驱动的分析和改造

基于STM32F407的SDCard读写操作及USB挂载(HAL库) 基于STM32F407的SDCard读写操作及USB挂载(HAL库版本) 阅读详情

From:http://www.csksoft.net/blog/post/linux_storage_mod.html

这原本是我这学期OS课程设计最后一次的作业,因为比较有意思,所以就把它公布出来吧。

作业要求:

开发Linux下的usb存储设备的驱动,仅需支持自己的u盘即可。

下面是我写的驱动,他基于linux下自带的usb-storage驱动(/driver/usb/storage)。仅支持基于Bulk-only传输模式下的ATAPI协议的存储设备。我使用自己的SAMSUNG D828手机的usb mass storage功能测试成功。

使用方法是insmod。

 

代码:

http://www.csksoft.net/data/legacyftp/Products/code_and_lib/csk_udisk_mgr.rar

 

下面是这次作业报告的节选,希望对需要研究usb-storage或者想自己开发linux u盘驱动(虽然那已经没有必要了)的朋友有帮助。这次报告的原文后面给出的地址。

 


 

1.USB MASS STORAGE 协议分析

Sub Class
协议名
说明
0x01
Reduced Block Commands(RBC)
 
通常为 Flash Rom 介质的存储设备使用
0x02
8020i, MMC-2(ATAPI)
通常为 CD/DVD 设备使用
0x03
QIC-157
常用于磁带机设备
0x04
UFI
常用于软磁盘设备 (FDD)
0x05
8070i
常用于软磁盘设备或者其他设备
0x06
SCSI 协议
 
0x07-0xFF
保留
 
摘录至 Universal Serial Bus, Mass Storage Class Specification Overview, P6

 

 Sub Class可以在usb设备连入系统后获取。不同的通讯协议决定了usb驱动要用不同的命令和数据包格式和u盘通讯。
 同时,白皮书还规定了u盘设备的通讯方式,见下表:

 

接口协议号
协议名
0x00
Control/Bulk/Interrupt 协议 (CBI)
带有 command completion 中断
0x01
Control/Bulk/Interrupt 协议 (CBI)
不带有 command completion 中断
0x50
Bulk-Only 协议
0x02-0x4F
保留
0x51-0xFF
保留
摘录至 Universal Serial Bus, Mass Storage Class Specification Overview, P7
 
         接口协议号即InterfaceProtocol字段,在usb设备插入后可以从总线上获取。
         在实际usb mass storage设备工作时,设备驱动首先要做的是获得该u盘的通讯协议和通讯方式,然后按照需要产生与目标设备兼容的控制命令,并将该控制命令打包通过设备的通讯传输方式发送至设备,完成一次对设备的读写操作。
         对于上述6中数据通讯协议,均有很详细的说明文档,经过分析,他们的命令有很大的相似之处,这也是通讯usb驱动能够实现的原因之一。

 

2.自带驱动usb-storage的简要原理分析

linux内核中自带的usb mass storage驱动位于内核源代码目录/drivers/usb/storage/下,下表为该目录下各文件的功能说明:
文件
功能说明
usb.c/.h
Usb-storage 的核心文件,是整个驱动的框架代码
transport.c/.h
实现了对于不同通讯方式的支持函数
scsiglue.c/.h
Scsi 设备的模拟函数
protocol.c/.h
实现了对于几种通讯协议的 SCSI 命令翻译函数
initializers.c/.h
对于某些设备的专用初始化函数
unusual_devs.h
对于非常规设备 ProductID 和 VendorID 的支持
shuttle_usbat.c/.h
支持 SCM Microsystems 设备的驱动
sddr55.c/.h
SanDisk SDDR-55 SmartMedia reader 的驱动
sddr09.c/.h
anDisk SDDR-09 SmartMedia reader 的驱动
onetouch.c/.h
Maxtor OneTouch USB hard drive 驱动支持
libusual.c
对于常规设备的 ProductID 和 VendorID 的支持
karma.c/.h
Rio Karma 设备驱动
jumpshot.c/.h
Lexar "Jumpshot" Compact Flash reader 驱动
isd200.c/.h
ISD200 专属通讯协议支持
freecom.c/.h
Freecom USB/IDE 转化器支持
dpcm.c/.h
DPCM-USB CompactFlash/SmartMedia reader 设备支持
debug.c/.h
用于调试的工具函数
datafab.c/.h
Datafab USB Compact Flash reader 驱动支持
alauda.c/.h
Alauda-based card readers 驱动支持
 
         通过上述文件作用分析后,可以看出,对于常规的usb设备,大部分代码文件都是多余的,核心文件为上表的前4项。这就为进一步分析驱动已经对其进行简化和仿制提供了可能。
         通过对核心代码的分析,本驱动的工作机理是将自身模拟为标准的SCSI设备,并向scsi管理器注册,这样对于上层系统而言,只需操作标准的SCSI设备即可。这样可以简化具体的文件读写功能。同时驱动接受到的SCSI命令转化为对应u盘设备的通讯协议,并用对应设备的通讯方式进行发送,并将结果回馈到SCSI管理器。
         下图展示了整个驱动的工作布局:
图中Transfer layer和protocol layer分别对应了transfer.c和protocol.c文件,Command Transfer Thread是usb.c在探测到有新设备接入后加载的线程,他将不断轮询SCSI发来的消息命令,并负责将这些命令通过protocol layer提供的函数翻译并发送到u盘上,完成对u盘的读写操作。
         Delayed Device Scan是为了防止用户在设备插入后马上拔除,造成驱动在后续通讯中造成混乱。实现方式是创建一个专门线程。
         同时,usb.c在设备插入是会通过scsiglue.c提供的SCSI接口函数向SCSI管理器注册自身。
 

3.对usb-storage的简化

经过上面对usb-storage的分析,可以将该驱动代码作如下方面的简化,方便后续的分析和驱动编写。
  1. 删除其中对罕见设备的支持
  2. 删除Delayed Device Scan机制
  3. 删除对于除了本次试验所用u盘设备外其他的通讯协议和通讯方式的处理函数。
  4. 对于仅调用一次的函数作inline处理

 

其中,每一项操作都会影响到原先的函数依赖关系,因而需要在删除代码或者文件前弄清楚其中的依赖关系。

 

按照原理中提到的步骤,首先是删除其对罕见驱动和专属驱动的支持。最终将保留下上面表格中前4项文件。
         同时处理usb.c对这些代码的引用,主要是在如下代码段中:
126 #ifndef CONFIG_USB_LIBUSUAL
127
128 #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
129                     vendorName, productName,useProtocol, useTransport, \
130                     initFunction, flags) \
//...//
181 #       undef USUAL_DEV
182
183         /* Terminating entry */
184         { NULL }
185 };
186
187
188 #ifdef CONFIG_PM        /* Minimal support for suspend and resume */
代码:原始 usb.c 中代码片断
 
         在这个区间中的代码将设置对不同设备,包括罕见设备ProductID和VendorID的支持。可以改为仅对D828设备的支持:
//SAMSUNG MOBILE USB INFO
#define USB_MASS_VENDOR_ID 0x04e8
#define USB_MASS_PRODUCT_ID        0x665c 
 
//REG IT
static struct usb_device_id storage_usb_ids [] = {
         { USB_DEVICE(USB_MASS_VENDOR_ID, USB_MASS_PRODUCT_ID) },
         { }                                          /* Terminating entry */
};
 
MODULE_DEVICE_TABLE (usb, storage_usb_ids);
代码:替换过 usb.c 后的代码
 
         当然,在后续的代码中,仍需要进行修改,比如us_unusual_dev_list[]在后续的引用也需要删除。
        
         在经过第一个简化操作后,便可以对D828协议以外的处理函数进行删除。在protocol.c中存在如下几个函数:
void usb_stor_qic157_command(struct scsi_cmnd *srb, struct us_data *us);
void usb_stor_ATAPI_command(struct scsi_cmnd *srb, struct us_data *us);
void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us);
void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, struct us_data *us);
代码: protocol.c 中提供的函数原形
 
         这正是针对白皮书中规定的4种不同的通讯协议的处理函数,而他们是通过usb.c中如下代码片断和当前设备进行联系的:
671 /* Get the protocol settings */
672 static int get_protocol(struct us_data *us)
673 {
674         switch (us->subclass) {
675         case US_SC_RBC:
676                 us->protocol_name = "Reduced Block Commands (RBC)";
677                 us->proto_handler = usb_stor_transparent_scsi_command;
678                 break;
679
680         case US_SC_8020:
681                 us->protocol_name = "8020i";
682                 us->proto_handler = usb_stor_ATAPI_command;
683                 us->max_lun = 0;
684                 break;
代码: usb.c 中 get_protocol 函数部分
 
         可以看到每个上述函数按照当前设备的subclass信息被赋值到us->proto_hander指针中。因而,可以只保留其中针对D828的函数,即 usb_stor_ATAPI_command ,同时删除get_protocol函数。
        
         基于同样的原理,可以对transfer.c和get_transport作相同的处理。
 
         接下来是对usb.c中的delayed device scan机制进行删除。因为本次试验不需要适应现实中各类特殊情况。
         在usb.c中usb_stor_scan_thread完成了对设备的延迟探索功能,其中代码段:
926                 /* For bulk-only devices, determine the max LUN value */
927                 if (us->protocol == US_PR_BULK &&
928                                 !(us->flags & US_FL_SINGLE_LUN)) {
929                         mutex_lock(&us->dev_mutex);
930                         us->max_lun = usb_stor_Bulk_max_lun(us);
931                         mutex_unlock(&us->dev_mutex);
932                 }
933                 scsi_scan_host(us_to_host(us));
934                 printk(KERN_DEBUG "usb-storage: device scan complete\n");
//...//
939         scsi_host_put(us_to_host(us));
940         complete_and_exit(&threads_gone, 0);
代码: usb_stor_scan_thread 函数片断
 
         上述代码完成了对设备的scan操作,而其他部分则与实际工作无关,因而可以将上述代码复制到storage_probe函数中对应位置,并删除函数usb_stor_scan_thread。

4.制作专用驱动

         在经过对系统自带代码的裁剪操作后,可以通过利用其中设备通讯等工具函数,以及仿造其中的框架重新制作D828的专属驱动。
a)         该操作按照下面的流程进行:
b)         放造usb.c编写框架代码
c)         将框架代码需要调用的工具函数和结构定义复制进本驱动代码
d)         在上次复制的函数中找到需要引用但尚未复制的函数,将他们添加近来
e)         查找仅引用过一次的函数,作inline处理
f)          其他的一些优化
 
         经过上述步骤以后,只要编译通过,该驱动便能顺利运行了。
 

 


 

报告原文,请勿随意抄袭!

ftp://FTP_Visitor:visitor@ftp.csksoft.net/Public/Article/osprj_mass_storage_csk.rar

orangepi-4-LTS g_mass_storage 模拟 U盘 orangepi-4-LTS 开发板通过 g_mass_storage 模拟U盘,通过 Type-C 接口与 PC 传输数据 阅读详情

相关推荐

如何使USB Mass Storage驱动支持CD-ROM格式

该文章讲解了有USB Mass Storage驱动升级到支持CD-ROM驱动

DennisGang的博客 5102

关于f_mass_storage.c的文章(转载)

原文地址:http://blog.youkuaiyun.com/HellDevil/archive/2010/05/18/5604421.aspx http://blog.youkuaiyun.com/HellDevil/archive/2010/05/06/5561918.aspx http://blog.youkuaiyun.com/HellDevil/archive/2010/01/19/5213888.aspx htt

wangyunqian6的专栏 5194

usb Mass Strorage分析(1)

接上一篇: usb-skeleton.c到 usb core层的分析 对于存储设备的USB,Linux源码中有关于USB MASS Storage 的驱动程序(/drivers/usb/storage下),其中/drivers/usb/storage/usb.c 实现了驱动初始化,和usb-skeleton.c 例子以一样,调用    retval = usb_register(&usb_sto

2636

如何实现Linux下的U盘(USB Mass Storage)驱动

摘要 本文主要介绍了USB Mass Storage的相关的各种协议之间的关系,以及如何在Linux的USB驱动框架下实现U盘驱动 本文提供多种格式供: 在线阅读 HTML HTMLs PDF CHM TXT RTF 下载(7zip压缩包) HTML HTMLs PDF CHM TXT

Lassewang的成长历程 5237

Linux Android USB gadget(从设备驱动)

Linux usb 通讯使用

帅的没拼音 2456

Linux下的USB总线驱动(三)

版权所有,转载请说明转自 http://my.youkuaiyun.com/weiqing1981127       4.U盘驱动分析 USB Mass Storage是一类USB存储设备,这些设备包括USB磁盘、USB硬盘、USB磁带机、USB光驱、U盘、记忆棒、智能卡和一些USB摄像头等,这类设备由USB协议支持。 首先我想去看看/driver/usb/storage/Makefile E

weiqing的专栏 4336

Linux usb mass-storage 阅读

usb core:实现核心的功能,为别的设备驱动程序提供服务,比如申请内存,比如实现一些所有设备都会需要的公共的函数,初始化整个usb系统,初始化root_hubusb host 控制器:控制所有的usb设备的通信,CPU不是直接和usb设备通信,而是和控制器通信,CPU要对设备做什么动作,它会告诉控制器,HC再去负责处理。

wangyongh的博客 1739

Blender----利用DEM(tif)生成三维模型

利用DEM(tif)生成三维模型

LongJ_Sir的博客 5423

【亲测免费】 USB Mass Storage Device_驱动下载仓库

USB Mass Storage Device_驱动下载仓库 【下载地址】USBMassStorageDevice_驱动下载仓库 本开源项目专注于提供USB Mass Storage Device驱动程序资源,帮助用户轻松安装或更新USB存储设备的驱动,确保设备与电脑系统的兼容性和稳定性。驱动文件适用于多种操作系统,包括...

gitblog_06750的博客 3210

AD20丝印层导入图片logo保姆级教程(附黑白预览避坑技巧)

本文提供了一份详尽的AD20丝印层导入图片Logo的实战指南。核心在于将图片预处理为高质量的单色BMP位图,并独家分享了利用Windows画图工具进行“黑白预览”的关键技巧,以提前规避转换失真。教程涵盖了从脚本获取、图片处理、参数设置到生产规范的完整流程,帮助硬件工程师高效、准确地在PCB的Top Overlay层添加个性化标识。

weixin_29194255的博客 386

解忧杂货铺(四):Hightec生成HEX方法+小功能开启

Hightec使用的一些常用技能

梦想技术家 2160

使用configfs配置usb mass storage设备

前面使用configfs配置了一个usb虚拟网卡设备. (cdc ecm) 这里使用configfs配置一个 mass storage设备 1. 准备文件系统, 可以使用实际的本地磁盘分区, 如/dev/mmcblk0p1, 也可以使用自己制作的loop回环块设备。 前提是有做过格式化, 且文件系统主机端能识别。 比如fat格式。 回环块设备制...

River的专栏 4854

HP DL380G9 iLO降级Degrated及存储失败storage Failed报错如何解决?

HP DL380G9 iLO降级(Degrated)及存储失败(storage Failed)报错如何处理? ©Lander Zhang 专注外企按需IT基础架构运维服务,IT Helpdesk 实战培训践行者https://blog.51cto.com/lander 2018/09/7 7:30 问题描述 某沙特公司搭建的虚拟化环境中有一台ESXi主机报Storage Fialed警告但是仍...

weixin_34226182的博客 4848

linux usb gadget驱动详解(三)

本文将对linux4.4.19版本usb gadget源码进行简单分析。鉴于前文反复测试U盘设备驱动,现从linux-4.4.19/drivers/usb/gadget/legacy/mass_storage.c开始分析。 目的是了解U盘设备驱动的工作原理,为啥它能让PC识别成“可移动磁盘”,以及它可以像市面上的U盘一样能读写文件。最后介绍内核gadget框架提...

mkelehk的专栏 1万+

autoDL算力云装Xinference[坑与步骤]

在页面直接点击下载会出现下着下载进度条消失,试了几次才出现这个报错,现在我们就继续安装缺少的包吧。这一步成功绕开了系统盘空间限制。先租用一个合适的服务器,建议不要选最新版本,跟我选的一样即可,不然后面会出现。最近在 AutoDL 上尝试部署。🚫 不要直接使用以下命令。点击下面链接即可打开。

ngadminq的博客 2382

31、MSP430FR2355时钟系统与低功耗模式解析

本文详细解析了MSP430FR2355的时钟系统和低功耗模式。首先介绍了时钟系统的组成,包括XT1振荡器、DCO、MODCLK、MCLK、SMCLK和ACLK的功能与配置方法。接着探讨了MSP430FR2355的五种低功耗模式及其配置要点,并分析了时钟系统与低功耗模式之间的协同关系。最后通过实际应用案例展示了如何在具体场景中优化系统功耗。文章旨在帮助开发者充分利用MSP430FR2355的时钟与低功耗特性,实现高性能、低功耗的嵌入式系统设计。

mars5的博客 195

[RK3288][Android6.0] USB Mass Storage流程小结

Platform: ROCKCHIP OS: Android 6.0 Kernel: 3.10.92 USB Mass Storage遵循Bulk-Only协议,参见: http://www.usb.org/developers/docs/devclass_docs/usbmassbulk_10.pdf 传输过程大概如下: 1. 插上设备之后USB Host读取描述符信

Kris Fei's blog 4824

4.3 Langfuse 集成实战:追踪 OpenAI、LangChain 和 LangGraph 应用

本文介绍了如何将Langfuse集成到不同类型的AI应用中,包括原生OpenAI、LangChain和LangGraph应用。主要内容包括: 两种集成模式:手动追踪(精确控制)和自动追踪(通过回调机制) 三种应用场景的集成方案: 原生OpenAI应用:使用langfuse.trace()手动记录对话流程、LLM调用和工具执行 LangChain应用:通过LangfuseCallbackHandler自动追踪Agent执行过程 LangGraph应用:与LangChain相同的自动追踪方式,可可视化节点和状态

yonggeit的博客 3303

USB Mass Storage

如标题所示,我们开始分析USB Mass Storage的架构. 那么driver的起点是哪里? LinuxSource/drivers/usb/storage/usb.c module_init(usb_stor_init); 这是一切的起点,好了现在要开始逐行分析usb_stor_init()这个函数了. static int __init usb_stor_init(v

2235

存储硬盘格式怎么把512还原为520格式??

硬盘厂商工具(如SeaChestsg_format)可以调整扇区大小。备份数据,因为调整扇区会清除硬盘内容。根据硬盘型号和接口类型,选择合适的工具进行调整。如果你需要更详细的帮助,请提供你的硬盘型号和存储设备类型。希望如上措施及解决方案能够帮到有需要的你。PS:如若遇到采纳如下方案还是未解决的同学,希望不要抱怨&&急躁,毕竟影响因素众多,我写出来也是希望能够尽最大努力帮助到同类似问题的小伙伴,即把你未解决或者产生新Bug黏贴在评论区,我们大家一起来努力,一起帮你看看,可以不咯。

**My Coding Family** 1146

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Linux usb mass,怎么实现Linux下的U盘(USB Mass Storage)驱动

第 2 章 USB Mass Storage大容量存储的基本知识目录2.1. USB Mass Storage相关的协议2.1.1. USB Mass Storage相关协议简介2.1.1.1. USB MSC Control/Bulk/Interrupt (CBI) Transport2.1.1.2. USB MSC Bulk-Only (BBB) Transport2.1.1.2.1. 为何U...

weixin_29015483的博客 1109

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

linux下usb 驱动

USB博大精深不是一篇文章就能够解释清楚的。想要深入研究USB的话,USB协议(外加Host和OTG协议)是必要的知识,另外,国内有本<<USB那些事>>也写的很好很详细,唯一美中不足的就是写得太详细了反而感觉思路架构不是很清晰了。今天我们来简单地把USB在Linux里的结构框架大致整理下,其中重点解析下USB Core和Hub。 0. 预备理论 说实话,读USB协议还是蛮痛苦的,它仅仅是一个协议,一个在USB世界里制定的游戏规则,就像法律条文一样,它并不是为了学习者而写的,可读

太初有道 7499

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: Linux-USB Gadget : Part 4: 最简单的 gadget驱动:g_zero
下一篇: Nand 驱动调试记录
asmxpl
博客等级 码龄15年 9粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值