0 基础知识
通常的USB设备可以分为五大类:显示器、通讯设备、音频设备、人机输入和海量存储。
而海量存储又包含了两大部分:传输方式和控制方式。
传输方式主要有:CBI传输和Bulk_only传输。
控制方式主要有:ATA命令(基本废弃)和UFI命令规范。
CBI即指:Control / Bulk / Interrupt。因此,Bulk_only传输可以看成CBI中包含的一种传输方式
需要注意U盘的Interface描述符:
UFI是SCSI命令的一个子集
UFI包含三种字长的命令:6bit、10bit、12bit,在window下通常使用12bit。
包含SCSI命令如下:
对于海量存储而言,上面标记了“●”的命令是必须响应。
具体命令格式参看:
1 具体协议流程:
1.1 获取一系列设备描述符:
1.2 查询分区
设备逻辑号范围是0到15,1表示有0、1两个逻辑设备。、
1.3 Bulk数据交换
传输过程有三个阶段:
CBW → DATA(Optional)→ CSW
CBW(Command Block Wrapper)长度31 Bytes,格式如下:
dCBWSignature:
CBW的标识,固定值:43425355h (little endian)。
dCBWTag:
主机发送的一个命令块标识,设备需要原样作为dCSWTag(CSW中的一部分)再发送给Host;主要用于关联CSW到对应的CBW。
dCBWDataTransferLength:
本次CBW命令要求在命令与回应之间传输的字节数。如果为0,则不传输数据。
bmCBWFlags:
反映数据传输的方向,0x00 表示来自Host,0x80 表示发至Host;
bCBWLUN:
对于有多个LUN逻辑单元的设备,用来选择具体目标。如果没有多个LUN,则写0。
bCBWCBLength:
命令的长度,范围在0~16.
CBWCB:
传输的具体命令,符合bInterfaceSubClass.中定义的命令规范,此处是SCSI指令集
CSW(Command Status Wrapper)长度13 Bytes,格式如下:
dCSWSignature:
CSW的标识,固定值:53425355h (little endian)
dCSWTag:
设置这个标识和CBW中的dCBWTag一致,参照上面关于dCBWTag的解释
dCSWDataResidue:
还需要传送的数据,此数据根据dCBWDataTransferLength-本次已经传送的数据得到
bCSWStatus:
指示命令的执行状态。如果命令正确执行,bCSWStatus 返回0 ,不正确返回1,phase错返回2(当HOST收到此错误时需要对Device复位)
大体命令流程如下:
0x12(Inquiry)
0x23(ReadFormatCapacity)
以上两个命令循环多次,需要Inquiry厂家信息、序列号,如果有多个逻辑设备也会都读回来,
PnP驱动初始化DEVICE_CAPBILITIES结构,
0x25(ReqadCapacity)
0x28(Read(10))
0x5A(ModeSense)(注:抓包显示Operation Code是0x1A,资料上都是0x5A不知道为什么)
0x2A(Write(10))
无数据时发送0x00(TestUnitReady),响应失败则发0x03(RequestSense)遇到异常则认为设备离线