Chinaunix首页 | 论坛 | 博客
  • 博客访问: 48569
  • 博文数量: 26
  • 博客积分: 1175
  • 博客等级: 少尉
  • 技术积分: 300
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-14 19:16
文章分类
文章存档

2011年(1)

2010年(25)

我的朋友

分类: 嵌入式

2010-05-07 21:36:55

S3C2440 USB U盘驱动读出U盘的容量和MBR扇区信息

由于LINUX有自带的查看USB的信息所以不用使用其他的软件来查看了

cat /proc/bus/usb/devices

下面就是我U盘的信息


T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 4 Spd=480 MxCh= 0

D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1

P: Vendor=2008 ProdID=2018 Rev= 0.00

S: Manufacturer=KINGSTON

S: Product=USB2.0Flash Disk

S: SerialNumber=O20070925A000796

C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA

I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage

E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms


首先看接口描述符,Interface Class = 8,表明是Mass Storage DeviceSub Class = 6,表明执行SCSI命令;Interface Protocol = 0x80,表明支持Bulk传输;另外,Number of Endpoints = 2,表明有两个端点。
两个端点描述符要注意的是,Endpoint Address = 1的是OUT端点,Endpoint Address = 2的是IN端点,有些可能会不一样;有些U盘可能还会有第三个端点,比如支持中断传输的U盘还会有一个Interrupt端点,不过这都没有关系。
都支持批量传输,且支持SCSI命令,所以,这可能是一个比较典型的例子,我们就以它为例。


其中,我们最关心的是Vendor=2008 ProdID=2018Manufacturer= KINGSTON Driver=usb-storage

对于这些移动存储设备,我们知道Linux下都是通过usb-storage.o驱动模拟成scsi设备去支持的,之所以不支持,通常是usb-storage驱动未包括此厂商识别和产品识别信息(在类似skel_probeUSB最初探测时被屏蔽了)。对于USB存储设备的硬件访问部分,通常是一致的。所以我们要支持它,仅需要修改usb-storage中关于厂商识别和产品识别列表部分。

然后再修改内核自动加载usb-storage模块。要不会有冲突的!


2 CBW(Command Block Wrapper)CSW(Command Status Wrapper)

首先要熟悉一下协议,有助于编写程序。

Universal Serial Bus Mass Storage Class Specification Overview

Universal Serial Bus Mass Storage Class -- Bulk-Only Transport

SCSI Primary Commands – 3(SPC-3)

SCSI Block Commands – 2(SBC-2)

一般只看传输协议和要用到的指令就可以了


第一个数据结构叫CBW(Command Block Wrapper)

   这个结构将承载具体的与设备有关的命令发送到设备上去,这个结构分成两部分,第一部分从byte[0]--byte[14]15个字节,第而部分从 byte[15]--byte[30]16个字节,整个数据结构为31个字节。规范中并没有定义第二部分的内容,这是因为第二部分承载的具体的命令,既 与命令集(SCSI命令集)有关,也与具体的命令有关,我们使用SCSI命令集,所以后16个字节的内容在前面提到的后面两个规范中有定义。

    比如我们要向设备发出一个SCSI命令INQUIRY(我们姑且先不要管命令的含义),那么这个命令的结构在SPC-3的第142页有定义,如下:


   
对于SCSI INQUIRY这条命令而言,CBW的第二部分的定义就是上面的这六个字节,不同的命令,定义也会不同。

    好,我们回到CBW的结构上来,根据规范,dCBWSignature的值必须是0X43425355,其实就是USBC这几个字母倒过来,这是因为 CBW的字符顺序是little endian(这个东东在以前有关网络编程的文章中介绍过),而我们PC机中的字符顺序是big endian,所以要颠倒一下,总之写dCBWSignature = 0X43425355OK了;dCBWTag仅仅是一个标志,你可以填任何值,这里要先说一下CSWCommand Status Wrapper),我们每发出一个命令,设备都会返回一个CSW(这个东东下面很快就要介绍了),以说明命令的执行状态,这个结构中也有 SignatureTag这两个字段,其中Tag字段和发出命令时CBW中的Tag字段相同,这样就可以区分这个CSW是和那个CBW对应的了,至于 Signature,下面再说。

    下一个字段是dCBWDataTransferLength,表示的是当这个命令发出后,我们希望设备返回数据的字符数或者我们要向设备传输的字符数,本 文仅涉及从设备返回数据,不涉及向设备传输数据;举例来说:我们发送INQIURY命令到设备,按照SPC-3144页的说明,该命令返回的数据至少为 36个字节,所以,此时这个字节应该填36;再如:我们读取U盘的一个扇区,如果扇区的长度是512个字节,那么这个字段就要填512

    再下来是bmCBWFlags字段,这个字段只有bit 7有意义,为0表示要向设备传输数据,为1表示要从设备获得数据。

    bCBWLUN字段总是填0,因为绝大多数的U盘都不支持多LUN(Logical Unit Number),只有一个逻辑单元自然好吗就是0了。

    bCBWCBLength字段是只CBW第二部分的长度,像前面举例的INQUIRY命令,长度为6个字节,则这个字段就应该填6,再 如:READ(10)命令的长度是10个字节(SBC-242页有定义),这个字段当然要填10了。

    第二个要说的数据结构是CSW,当hostdevice发送一个CBW后,接着就可以从device收到数据(或者发数据到device),当接受完所 需的的数据后,就可以从device获得一个CSW(Command Status Wrapper)CSW的结构如下:

     前面说过,在CBW中的dCBWSignature的值恒为:0x43425355,得到的CSW中的dCSWSignature的值 为:0x53425355dCSWTagdCBWTag中的一致。

    在得到的CSW中,恒定有13个字节,bCSWStatus的定义如下:

我们知道USB协议中定义了三种传输方式,控制传输、批量传输、中断传输和实时传输,在《USB系列二》中我们一 直都在使用控制传输,我们应该比较熟悉了,本文中将涉及批量传输。

    我们在使用控制传输时,我们设置好URB启动传输事务,相应的结果将返回到制定得buffer中,批量传输没有那么简单,批量传输分为输出事务和输入事 务,我们应该注意到,前面在看U盘的描述表时,在端点这一级有两个端点,一个叫OUT端点,一个叫IN端点,当我们启动一个输出事务时,一定要发送给 OUT端点,当我们启动一个输入事务时,一定要发送到输入端点。下面我们简单描述一下如何启动批量传输事务。

由于在S3C2440的时候使用INQUIRY的时候U盘会自动重启。所以。就直接跳过。使用READ CAPACITY(10)READ(10)命令。

还有定义3 CMND_STRUCTCBWCSW结构体

struct bulk_cb_wrap {

__u32 Signature;

__u32 Tag;

__u32 DataTransferLength;

__u8 Flags;

__u8 Lun;

__u8 Length;

__u8 CDB[16];

};

struct bulk_cs_wrap {

__u32 Signature;

__u32 Tag;

__u32 Residue;

__u8 Status;

__u8 Filler[18];

};


struct cmnd_struct {

unsigned char cmnd[MAX_COMMAND_SIZE];

unsigned char cmd_len;

unsigned char sc_data_direction;

unsigned data_payload_size;

unsigned data_payload_actualSize;

__u32 tag;

};

例如自己模拟一个SCSI 命令INQUIRY

com->cmnd[0] = 0x12;

com->tag = 0;

com->sc_data_direction = SCSI_DATA_INQUIRY;

com->cmnd[1] = 0;

com->cmnd[4] = 36;

com->cmd_len = 6;


参照USB自带的usb-skeleton.c编写!


还要介绍一下下面内容

主引导记录(MBR)

绝对扇区号为: MBR_LBA=0x00000000 处是主引导记录,等同位于硬盘的 0 磁道 0 柱面 1 扇区。

在总共 512 字节的主引导扇区中,MBR 只占用了其中的 446 个字节(ofs:0 - ofs:1BDH) ,

另外的 64 个字节(ofs:1BEH - ofs:1FDH)交给了 DPT(Disk Partition Table 盘分区表),

最后两个字节“55 AA” ofs:1FEH - ofs:1FFH)是分区的结束标志。

MBR 定义如下:

typedef struct {

uchar bootcode[446]; //ofs:0.启动代码。 “FA 33 C0 8E D0 BC…”.

PartitionTable PT[4]; //ofs:446.分区表 length=4*16.

uint EndingFlag; //ofs:510.结束标识:0xAA55.

}MBR_tag;

Bootcode[446]启动代码一般是固定的,用于引导 x86,不用管。

分区表项的定义如下:

typedef struct {

uchar BootFlag; //启动标志

CHS StartCHS; //分区开始的柱面、磁头、扇区

uchar SystemID; //分区类型

CHS EndCHS; //分区结束的柱面、磁头、扇区

ulong RelativeSectors; //分区起始扇区数,指分区相对于记录该分区的分区表的扇

区位置之差 (该分区表:LBA=0x0)

ulong TotalSectors;//分区总扇区数

}PartitionTable;

其中 CHS 为一个柱面、磁头、扇区的结构,定义如下:

struct CHS {

uchar Head; //磁头。

unsigned Sector : 6; //扇区。

unsigned CyH2 : 2; //柱面(高两位)

uchar CyL8; //柱面(低八位) 。

ulong Cylinder() {return (uint(CyH2)*256+CyL8);} //返回柱面值

void SetCylinder(uint Cylinder) //设置柱面值 {

CyH2=(Cylinder>>8)&0x3; CyL8=(Cylinder&0xff);

}

};

例:80 01 01 00 0B FE BF FC 3F 00 00 00 7E 86 BB 00


在这里我们可以看到:

80”是一个分区的激活标志,表示系统可引导;

01 01 00”表示分区开始的磁头号为 01,开始的扇区号为 01,开始的柱面号为 00

0B”表示分区的系统类型是 FAT32,其他比较常用的有 04FAT16)、06bigFAT16)、

01FAT12)、07NTFS

FE BF FC”表示分区结束的磁头号为 254,分区结束的扇区号为 63、分区结束的柱面

号为 764

3F 00 00 00”表示首扇区的相对扇区号为 63

7E 86 BB 00”表示总扇区数为 12289622

下面就是我U盘读取扇区的内容subminor is 0 The device is c3d8fba0                                            
USB Skeleton device now attached to USBmyudisk-195                              
doDefault 0, data length 8                                                      
Bulk command S 0x43425355 T 0x1 Trg 0 LUN 0 L 8 F 128 CL 10                     
Bulk command transfer result=0, xferred 31/31                                   
xfer 8 bytes data                                                               
Bulk data transfer result: 0, xferred 8/8                                       
Attempting to get CSW...                                                        
Bulk status transfer result = 0, xferred 13/13                                  
Bulk status Sig 0x53425355 T 0x1 R 0 Stat 0x0                                   
transport indicates command was successful                                      
To the after the read capity!                                                   
The size is 2107637760,The block size is 512,the num is 4116480                 
doDefault 1, data length 512                                                    
Bulk command S 0x43425355 T 0x12345679 Trg 0 LUN 0 L 512 F 128 CL 10            
Bulk command transfer result=0, xferred 31/31                                   
xfer 512 bytes data                                                             
Bulk data transfer result: 0, xferred 512/512                                   
Attempting to get CSW...                                                        
Bulk status transfer result = 0, xferred 13/13                                  
Bulk status Sig 0x53425355 T 0x12345679 R 0 Stat 0x0                            
transport indicates command was successful                                      
The disk started at sector 32.                                                  
The disk has 4116416 sectors.                                                   
The disk offset with 32 sectors.                                                
Next is the disk MBR and DPT information.                                       
fa                                                                              
33   c0   8e   d0   bc   0   7c   8b                                            
f4   50   7   50   1f   fb   fc   bf                                            
0   6   b9   0   1   f2   a5   ea                                               
1d   6   0   0   be   be   7   b3                                               
4   80   3c   80   74   e   80   3c                                             
0   75   1c   83   c6   10   fe   cb                                            
75   ef   cd   18   8b   14   8b   4c                                           
2   8b   ee   83   c6   10   fe   cb                                            
74   1a   80   3c   0   74   f4   be                                            
8b   6   ac   3c   0   74   b   56                                              
bb   7   0   b4   e   cd   10   5e                                              
eb   f0   eb   fe   bf   5   0   bb                                             
0   7c   b8   1   2   57   cd   13                                              
5f   73   c   33   c0   cd   13   4f                                            
75   ed   be   a3   6   eb   d3   be                                            
c2   6   bf   fe   7d   81   3d   55                                            
aa   75   c7   8b   f5   ea   0   7c                                            
0   0   49   6e   76   61   6c   69                                             
64   20   70   61   72   74   69   74                                           
69   6f   6e   20   74   61   62   6c                                           
65   0   45   72   72   6f   72   20                                            
6c   6f   61   64   69   6e   67   20                                           
6f   70   65   72   61   74   69   6e                                           
67   20   73   79   73   74   65   6d                                           
0   4d   69   73   73   69   6e   67                                            
20   6f   70   65   72   61   74   69                                           
6e   67   20   73   79   73   74   65                                           
6d   0   0   0   0   0   0   0                                                  
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   c                                                   
fa   97   90   0   0                                                            
Now is the partition table.                                                     
80  

1   1                                                                   0   6   7d   e0   ff   20   0   0                                               
0   c0   cf   3e   0   0   0   0                                                
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   0   0   0                                                   
0   0   0   0   0   55   aa    

        



阅读(1084) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~