2024年4月8日发(作者:)
Linux下USB MASS STORAGE驱动的分析笔记
MASS STORAGE 协议分析
Sub Class
0x01
协议名
说明
通常为Flash Rom介质的存储设备使用
通常为CD/DVD设备使用
常用于磁带机设备
常用于软磁盘设备(FDD)
常用于软磁盘设备或者其他设备
Reduced Block Commands(RBC)
0x02
8020i, MMC-2(ATAPI)
0x03
QIC-157
0x04
UFI
0x05
8070i
0x06
SCSI协议
0x07-0xFF
保留
Sub Class可以在usb设备连入系统后获取。不同的通讯协议决定了usb驱动要用不同的命令
和数据包格式和u盘通讯。
接口协议
号
0x00
0x01
协议名
Control/Bulk/Interrupt 协议(CBI)
带有command completion中断
Control/Bulk/Interrupt 协议(CBI)
不带有command completion中断
Bulk-Only协议
保留
保留
0x50
0x02-0x4F
0x51-0xFF
接口协议号即InterfaceProtocol字段,在usb设备插入后可以从总线上
获取。
在实际usb mass storage设备工作时,设备驱动首先要做的是获得
该u盘的通讯协议和通讯方式,然后按照需要产生与目标设备兼容的控制命令,
并将该控制命令打包通过设备的通讯传输方式发送至设备,完成一次对设备的读
写操作。
对于上述6中数据通讯协议,均有很详细的说明文档,经过分析,他
们的命令有很大的相似之处,这也是通讯usb驱动能够实现的原因之一。
2.自带驱动usb-storage的简要原理分析
linux内核中自带的usb mass storage驱动位于内核源代码目录
kernel/drivers/usb/storage/下,下表为该目录下各文件的功能说明:
文件
功能说明
usb.c/.h
transport.c/.h
scsiglue.c/.h
protocol.c/.h
initializers.c/.h
unusual_devs.h
shuttle_usbat.c/.h
sddr55.c/.h
sddr09.c/.h
onetouch.c/.h
libusual.c
karma.c/.h
jumpshot.c/.h
isd200.c/.h
freecom.c/.h
dpcm.c/.h
debug.c/.h
datafab.c/.h
alauda.c/.h
Usb-storage的核心文件,是整个驱动的框架代码
实现了对于不同通讯方式的支持函数
Scsi设备的模拟函数
实现了对于几种通讯协议的SCSI命令翻译函数
对于某些设备的专用初始化函数
对于非常规设备ProductID和VendorID的支持
支持SCM Microsystems设备的驱动
SanDisk SDDR-55 SmartMedia reader的驱动
anDisk SDDR-09 SmartMedia reader的驱动
Maxtor OneTouch USB hard drive驱动支持
对于常规设备的ProductID和VendorID的支持
Rio Karma设备驱动
Lexar "Jumpshot" Compact Flash reader驱动
ISD200专属通讯协议支持
Freecom USB/IDE 转化器支持
DPCM-USB CompactFlash/SmartMedia reader设备支持
用于调试的工具函数
Datafab USB Compact Flash reader驱动支持
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的传输协议
Mass Storage类支持两种传输协议:
1、Bulk-Only 传输(BOT)
2、Control/Bulk/Interrupt传输(CBI)
Mass Storage类规范定义了两个类规定的请求。Get_Max_Lun和Mass Stroage
Reset,所有的Mass Storage设备都必须支持这两个请求。
Mass Storage Reset(bmRequestType=00100001b and bRequest=11111111b)用
来复位Mass Storage设备及相关接口。
Get_Max_Lun(bmRequestType=00100001b and bRequest=11111110b)用来确认设
备支持的逻辑单元数。Max Lun的值必须是0—15。注意Lun必须是从0开始的。
主机不能向不存在的Lun发送CBW。
支持BOT传输的Mass Storage设备接口描述符要求如下:
接口类代码bInterfaceClass=08h,表示为Mass Storage设备。
接口类子代码 bInterfaceProtocol有3种:0x00,0x01,0x50,前两种使用中断
传输,最后一种使用批量传输(BOT)。
支持BOT的设备必须支持最少3个endpoint:Control,Bulk-in,Bulk-out。
USB2.0的规范定义了控制端点0。Bulk-in端点用来从设备向主机传送数据,
Bulk-out 端点用来从主机向设备传送数据。
Bulk-Only传输(BOT)
像控制传输一样,Bot也是由command阶段,可选的数据阶段和状态阶段组成。
所有的Command命令都有可能没有Data阶段。下图说明了BOT的Command传输,
Data-in,Data-out传输及Status传输。
Bulk-only传输示意图
CBW是由31个字节组成的短包。 CWB和后续的数据以及CSW都是从新封装包
开始的。要注意的是所有的CBW传输都是little-endian模式。
在CBW中,dCBWsignature必须是“43425355h”,表示是CBW封装包。dCBWTag
是CB标签,会通过对应的CSW反馈回来。
在CSW中,dCSWSignature必须是“53425355h”,表示是CSW封装包。


发布评论