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封装包。