原贴地址:
http://blog.csdn.net/luckywang1103/article/details/11981593
USB Mass Storage类规范概述
USB Mass storage Device协议即海量存储设备协议适用于硬盘,U盘等大容量存储设备。协议使用的接口端点有BulkIn、BulkOut和Interrupt端点。该设备类又包含6个独立的子类以及3种传输协议。
Bulk- Only 传输规范仅仅使用Bulk 端点传送数据/命令/状态,CBI 传输规范则使用Control/Bulk/Interrupt 三种类型的端点进行数据/命令/状态传送。
我们手中的U盘就是遵循SCSI协议的。要知道U盘不仅仅是USB设备,它还是一种存储设备,类似硬盘,USB协议本身没有定义对存储设备操作的指令,所以需要通过SCSI来完成读写等操作。
Microsoft Windows 中提供对Mass Storage 协议的支持,因此USB 移动设备只需要遵循 Mass Storage 协议来组织数据和处理命令,即可实现与PC 机交换数据。而Flash 的存储单元组织形式采用FAT16 文件系统,这样,就可以直接在Windows的浏览器中通过可移动磁盘来交换数据了,Windows 负责对FAT16 文件系统的管理,USB 设备不需要干预FAT16 文件系统操作的具体细节。
USB成功枚举之后会在设备管理器上面显示USB MassStorage Device(且带有黄色感叹号),否则会显示unknow device,
而只有在进行UFI(具体是在inquiry命令之后)通讯之后主机才会显示盘符,且本来在设备管理器中USB MassStorage Device上的黄色的感叹号消失。
因为这个时候USB设备已经枚举成功(主机发送的GetDescriptor、SetAddress等之类的请求都回复成功才能正确的枚举),所以可以通过BusHound来查看在USB UFI Command的情况,USB设备的枚举都是通过端点0来实现,而USB UFI Command都是通过端点1来实现,所有的命令的数据流都在端点1。除了BusHound之外,还有很多查看USB总线数据的软件,例如USB View等,查看Flash数据的软件有winhex。
枚举过程CATC仪器抓取数据的文件:http://download.csdn.net/detail/luckywang1103/6315437 usbUFI.usb
1、GetMaxLun(0xFE)
1)Setup Stage
2)Data Stage
3)Status Stage
以上这个阶段对应的程序是
[plain] view plaincopyprint?
- case GetMaxLun:
- //实际上对U盘来说,忽略该步骤也没有影响
- //要求设备返回一个字节给主机,以表明USB设备有多少个
- //逻辑设备,返回的数据就是这个最大设备逻辑号(0到15)
- //如果返回2,代表有0、1、2三个逻辑设备
- SFR_Write(FIFO0,0x00);
- SFR_Write(E0CSR,0x0a);
- break;
case GetMaxLun:
//实际上对U盘来说,忽略该步骤也没有影响
//要求设备返回一个字节给主机,以表明USB设备有多少个
//逻辑设备,返回的数据就是这个最大设备逻辑号(0到15)
//如果返回2,代表有0、1、2三个逻辑设备
SFR_Write(FIFO0,0x00);
SFR_Write(E0CSR,0x0a);
break;
接下来开始在端点1进行UFI Command传输
UFI Command构成如下:CBW—>数据—>CSW,三个阶段
CBW:Command Block Wrapper 命令块数据包
CSW:Command Status Wrapper 命令执行状态
2、Inquiry Command(0x12)
1)CBW
主机在端点1所发出的UFI Command的DATA0数据可以对照图Table 5.1进行解析。
dCBWSignature:55 53 42 43 help identify this data packet as CBW
dCBWTag:90 C8 E8 88 Command Block Tag send by host
dCBWDataTransferLength:24 00 00 00 data numbers that host expect to transfer on the Bulk-In or Bulk-Out endpoint
剩余的12 Bytes就是CBWCB:12 00 00 00 24 00 00 00 00 00 00 00
CBWCB(CBW里面的command block)12个字节的解析参考《USB Mass Storage Class-UFI Command Specification》
12:Inquiry Command
24:Allocation Length specifies the maximum number of bytes of inquiry data to be returned,数据阶段最大传送36 Bytes
2)Data In
这36 Bytes是按照Inquiry data的格式要求返回的,具体协议数据的分析参考《USB Mass Storage Class-UFI Command Specification》
3)CSW
dCSWSignature:55 53 42 53 help identify this data packet as CSW
dCSWTag:90 C8 EB 88 CSW的这个字段同CBW的dCBWTag字段
3、Read_Format_Capacity(0x23)
1)CBW
2)Data
3)CSW
4、Read_Capacity(0x25)
1)CBW
2)Data
3)CSW
5、Read_10(0x28)
上面几个请求如果均正确返回,Host会发出Read读文件系统0簇0扇区的DBR数据,进入文件系统识别阶段。
1)CBW
2)Data
3)CSW
6、ModeSense6(0x1A)
1)CBW
2)Data
3)CSW
7、重复第6步,ModeSense6(0x1A)
8、重复第4步,Read_Capacity(0x25)
9、重复第4步,Read_Capacity(0x25)
10、重复第5步,Read_10(0x28)
11、重复第5步,Read_10(0x28)
12、重复第4步,Read_Capacity(0x25)
13、重复第4步,Read_Capacity(0x25)
14、重复第5步,Read_10(0x28)
15、Test Unity Ready(0x00)
1)CBW
3)CSW
16、重复第4步,Read_Capacity(0x25)
17、重复第4步,Read_Capacity(0x25)
18、重复第4步,Read_Capacity(0x25)
19、重复第5步,Read_10(0x28)
20、接下来一直会重复Test Unity Ready(0x00)
说明:
MASS Storage设备所使用的SCSI命令集
0x00: testUnityReady 0x03: Request Sense
0x12: Inquiry
0x1A: ModeSense6
0x1B: StartStop
0x1E: MediumRemoval
0x23: ReadFormatCapacity
0x25: ReadCapacity
0x28: Read10
0x2A: Write10
0x2F: Verify
0x5A: ModeSense10
主机首先发出Inquiry命令,响应了Inquiry之后就可以看到盘符.
Inquiry之后会发出ReadFormatCapacity命令,这个命令在SCSI规范中是“厂家自定义命令”,可以参考UFI命令集文档(实际 上,U盘所使用的所有SCSI命令集都可以参考UFI文档,它比SCSI标准文档更简洁明了)。注意这个命令在BusHound里是没有描述的,必须在 “Device”选项页里勾选上这个U盘所对应的USB Mass Storage Device这个节点,才能看到这个命令的数据流。
ReadFormatCapacity之后会发出ReadCapacity命令。
U盘读数据(读扇区)时会发送Read(10)。ReadCapacity完成后就会发送Read(10)读取U盘的第一个扇区。
U盘写数据时(写扇区)会发送Write(10)。
TestUnitReady会在无其他数据传输时会定时发送,如果设备没有回应成功的CSW给主机,则主机认为设备已不存在。此时如果再双击磁盘图 标,Windows会提示“请插入磁盘”。
Verify在写数据时有用,表示核实数据,一般直接返回成功的CSW就可以了。一般来说,数据校验的工作在接收和向介质写数据时就已经顺带做了,如果发 现错误,则直接告诉主机那次的数据传输有误,不会等到主机Verify时。当然,这不是一个必然的方案。
RequestSense:如果CSW指示此次传输不成功,那么主机会发出此请求。
StartStop暂时未发现大用处,一般直接返回成功的CSW。
MediumRemoval在U盘被Eject的时候有用,处理不正确会Windows会弹出错误信息。
ModeSense6/10这两个命令可以不支持(不支持不代表不反应,任何一个命令你都要做出反应,对于不支持的命令,可以通过STALL握手来向主机 表明),暂时也未遇到过什么异常情况,而且我查看过一些U盘,有相当一部分就是随便回了几个数据给主机。这两个命令只会在U盘插入后发送一次,此后不再发 送。