USB Mass Storage Class

编辑博客时,回车的意思是切换段落,shift+回车才是换行。
SCSI Interface Controller: AMD am5380

1 USB Flash Drive Controller
1.1 USB Flash Drive Controller
ST 2005 ST72681 and 2007 ST72682, Alcor AU6980, Innostor IS917 with 8051.
Refer to 4.3.2 Bad block replacement of ST72681 datasheet.
一般一个CE对应一个LUN,一个CE控制一块NAND Flash。
Kinston:SSS主控
Sandisk:自己生产主控,Toshiba NAND,不开放量产工具

1.2 U盘量产工具 - 主控芯片私有的SCSI命令
DT101 G2: SSS6801 H1-U6C, Phison HVKK0FF 115T134G-3S-1X
NAND的坏块信息保存在OOB中,因为SCSI协议无法访问NAND OOB,所以SCSI协议无法知道NAND哪些block是坏块。

ChipEasy / ChipGenius
FlashGenius
MyDiskTest

HS握手时,Chirp KJ的频率大概是10KHz。

2 SCSI CDB
2.1 已经定义了CBI,为何又再定义一个BBB
USB MSC传输层协议分CBI(Control/Bulk/Interrupt)和BOT(Bulk-only Transport),而BOT又称为BBB。

对于USB MSC设备来说,USB设备和USB主机之间的通信,既然已经定义了一个CBI规范,那么为何还要再新定义一个BBB呢?

因为最开始USB协议定义的时候,那时候市场上的Floppy Disk还是用的很多的。所以针对Floppy设备特点,分别定义了多个端点来传输不同的信息,即Control端点传命令块,Bulk传数据,Interrupt传状态信息。而后来计算机行业发展了,Floppy类的设备很少用了,存储数据多数开始用Flash Memory了,再加上通过合理规划,可以用同一种端点(Bulk),传输上述三种信息,即命令块,数据,状态。因此,只需要物理上实现2个Bulk端点,节省掉了其他两个端点(Control端点和Interrupt端点),而达到同样的信息传输的目的。

常见的大容量存储设备的bInterfaceClass、bInterfaceSubClass和bInterfaceProtocol分别如下所示。
UFI CBI:0x08/0x04/0x00
UFI BOT:0x08/0x04/0x50
SCSI CBI:0x08/0x06/0x00
SCSI BOT:0x08/0x06/0x50
SFF-8070i/ATAPI BOT(移动硬盘用):0x08/0x05/0x50

Linux系统处理UFI和SCSI命令集参考如下的代码。
drivers/usb/storage/usb.c
get_transport(us);
get_protocol(us);

2.2 CBW and CSW
31个字节长度的USB CBW报文的前15个字节是固定的头,从偏移15开始到偏移30结束是16个字节长度的SCSI CDB。
13个字节长度的USB CSW的最后一个字节表示SCSI CDB执行状态,0表示成功,1或者2表示失败。

2.3 Format Unit
SCSI指令Format Unit和Mode Select,可以一定程度改变HDD的工作模式,其中包括扇区尺寸。由于能够改变扇区的定义,所以这2个指令可以看着是对HDD的低级格式化操作。

低级格式化历史:HDD一个完整扇区包括头部总计15字节的间隙(Gap)部分、同步(Sync)部分和地址标记(Address Mark)部分,总计512字节的数据(Data)部分,以及最后50字节的ECC部分,这些都是在低级格式化时所确定的。

2.4 Inquiry
Figure 2-1 标准Inquiry返回数据
20180517141349179
Peripheral Device Type(PDT):标识当前连接逻辑单元的类型,0x00为直接存储设备,0x05为光盘
Removable Media Bit(RMB):置1表示U盘,置0表示HDD
Response Data Format:UFI设备置1,SCSI-2设备置2
Additional Length:参数长度,此值为31
Vendor Information:8个字节长度的ASCII字符串,不包括''
Product Identification:16个字节长度的ASCII字符串,不包括''
Product Revision Level:4 hexadecimal digits,不包括''

2.5 Mode Sense 6
unsigned char
usb_stor_mode_sense6_wp[4] = {
    [0] = 3,
    [1] = 0x00,
    [2] = 0x80, /* bit 7 = WP */
};
When the number of bad sectors is greater than the threshold, which will cause USB flash drive enters write protect.

2.6 Read Capacity
返回的是最大扇区数目减1,即是num_sectors - 1。

2.7 Read10
CDB (SCSI Command Descriptor Block) 包中的offset 2 - 5是LBA,offset 7 - 8是扇区数目。

char umass_event[] = "UMASS_ERR=1";
char umass_port[32];
char *umass_env[] = {umass_event, umass_port, NULL};
kobject_uevent_env(&us->pusb_intf->dev.kobj, KOBJ_CHANGE, umass_env);

2.8 Request Sense
Figure 2-2 Request Sense
20180521092224173
Valid:表示Information域是否有效
Information:4个字节的sense_data_info,表示出错的逻辑块地址
Additional Sense Length:值是10
SK、ASC、ASCQ:组成一个24bit的sense_data(大端格式),表示错误代码

USB host MSC(transport.c)每发送一个命令后,都会检测设备返回的CSW的状态值是否为0(Good Status),如果不为0,则USB host MSC马上发送REQUEST_SENSE命令,获取18字节的出错信息,并保存在srb->sense_buffer中供SCSI层分析。

drivers/usb/storage/transport.c
usb_stor_invoke_transport()
srb->sense_buffer

// SS_MEDIUM_NOT_PRESENT = 0x023a00
sense_key = 2;
asc = 0x3a;
ascq = 0x00;

3 Linux内核SCSI子系统
3.1 Linux Mass Storage Gadget
do_scsi_command() - 假如读写时由N个buffer,那么这个函数传输的buffer范围是从[1, N - 1],最后一个buffer由finish_reply()完成传输
finish_reply()            - 传输最后一个buffer
send_status()           - 完成CSW状态

3.2 SCSI Host注册使用到的函数
scsi_host_alloc()
scsi_add_host()
scsi_scan_host() - 执行INQUIRY命令,每扫描到一个lun(函数scsi_probe_and_add_lun())就创建一个struct scsi_device(譬如U盘一般只有一个lun,而读卡器和UFS可能有多个lun;每个struct scsi_device创建一个disk,可能有多个分区),与sd_probe()匹配。

3.3 sync执行流程
3.3.1 sys_sync
sys_sync()
wakeup_bdflush(0)
sync_inodes(0)
sync_supers()
sync_filesystems(0)
sync_filesystems(1)
sync_inodes(1)

3.3.2 命令行执行sync流程
SYSCALL_DEFINE0(sync)
->
wakeup_flusher_threads()

3.4 TUR执行流程
3.4.1 methodology
drivers/usb/storage/scsiglue.c
queuecommand_lck()
add dump_stack() to find who calls TUR.

3.4.2 enable TUR polling
echo 2000 >
/sys/module/block/parameters/events_dfl_poll_msecs

dfl means default.

3.4.3 Construct TUR Fail CDB
If the device is not ready, the bCSWStatus field in CSW is set to 0x01 (command failed). When device reports 00h in the bCSWStatus field in CSW, which indicates that media is ready.

// srb->sense_buffer
unsigned char
usb_stor_sense_media_notpresent[18] = {
    [0] = 0x70,
    [2] = 2,           /* Sense Key */
    [7] = 0x0a,
    [12] = 0x3a,   /* ASC */
    [13] = 0,         /* ASCQ */
};

3.5 usb层和scsi层传自定义参数
通过struct Scsi_Host {}

3.6 scatterlist转换为内存虚拟地址
struct scatterlist *scatterlist;
void *kaddr;

获取scatterlist
struct page *page = sg_page(&scatterlist[i]);
kaddr = kmap(page);

4 Android StorageManagerService
4.1 vdc - mConnector
抓取log
dumpsys mount
logcat | grep StorageManagerService

4.2 获得系统所有的存储卷
userdata分区是Android必须的一个分区,作为内置存储,一般也是加密后的分区(vold FBE EXT4_IOC_SET_ENCRYPTION_POLICY),但是userdata需要在vold启动之前挂载,所以它并不归vold管理,而是由init进程挂载。在init进程挂载完内置分区后,就会启动vold进程来处理外置分区。vold需要在内置分区/data下面模拟外置主分区(data/media)。

Framework StorageManagerService通过2个socket连接vold进程,一个是vold处理挂载类工作(包括App2SD的Asec和APK数据包OBB文件),另外一个是cryptd处理加密工作。

StorageManager mStorageMgr =
 (StorageManager)this.getSystemService(Context.STORAGE_SERVICE);
StorageVolume[] vlists = mStorageMgr.getVolumeList();
String str = "";
for (StorageVolume sv: vlists) {
    str += "path: " + sv.getPath() + " ";
}
// /storage/emulated/0
str += Environment.getExternalStorageDirectory().getPath();
tv.setText(str);

4.3 storage_list.xml
StorageManagerService.java
onVolumeCreatedLocked()
{
    ...
    if (... || vol.disk.isSd()) // /storage/UUID
    ...
}

5 Abbreviations
ARC:Argonant RISC Core
AT91SAM9260:SAM means Smart ARM-based Microcontroller
ATMEL SAMBA:ATMEL Smart ARM-based Microcontroller Boot Assistant
bdi:backing device info - 脏页写回核心结构;文件系统page cache,使用struct address_space_operations(每个文件系统都有这个结构体,譬如 fat_aops)
DBR:DOS Boot Record
DWC2:Design Ware Controller 2,Apple的嵌入式设备,包括iPad和iPhone都是使用的DWC2
EBR:Extended Boot Record
IDA & IDR:Identification,IDR机制在Linux内核中指的是整数ID管理机制。实质上来讲,这就是一种将一个整数ID号和一个指针关联在一起的机制。IDA是用IDR来实现的ID分配机制,与IDR的区别是IDA仅仅分配与管理ID,并不将ID与指针相关联。
ISP1161:Philips' Integrated host Solution Pairs 1161,“Firms introduce USB host controllers”,https://www.eetimes.com/document.asp?doc_id=1290054
Linux dd命令参数:if表示input file,of表示output file,bs表示block size
MBR:Main Boot Record
MMC-2:SCSI Multimedia Commands-2
MGX:三星SSD主控
NTFS:n ei f ts
ps2251-63:Phison(Phison = “Five-Person”, 由五位Flash 研发经验超过14年专业人士创立),群联
RCU:Read-Copy Update,RCU支持一个更新者和多个读者同时访问。通过维护对象的多个版本,RCU保证读者看到的对象是前后一致的,并且保证在所有之前已存在的读者离开临界区时,这些版本才会被释放
SFF-8020i:Small Form Factor Committee,小型化委员会
SL811HS:Cypress/ScanLogic 811 Host/Slave,性能上与ISP1161(Integrated host Solution Pairs 1161)相当
SSS:Solid State System,鑫创,简称3S
TDI:TransDimension Inc.,该公司首先发明了将TT集成到EHCI RootHub中的方法,这样对于嵌入式系统来说,就省去了OHCI/UHCI的硬件,同时降低了成本,作为对该公司的纪念,Linux内核定义了宏ehci_is_TDI(ehci);产品UHC124表示USB Host Controller;收购了ARC USB技术;现已被chipidea收购,chipidea又被mips收购
TT:Transaction Translator(事务转换器,将USB2.0的包转换成USB1.1的包)
TUR:Test Unit Ready(类似心跳信号),sd_spinup_disk()执行该命令,底层排队函数
USB BH reset:Bigger Hammer or Brad Hosler,表示warm reset;you may be confused why the USB 3.0 spec calls the same type of reset "warm reset" in some places and "BH reset" in other places. "BH" reset is supposed to stand for "Big Hammer" reset, but it also stands for "Brad Hosler". Brad died shortly after the USB 3.0 bus specification was started, and they decided to name the reset after him. The suggestion was made shortly before the spec was finalized, so the wording is a bit inconsistent.
usb_stor_host_template.queuecommand()和ufshcd_queuecommand()。Linux工具sg_turs(SCSI Generic,隶属于sg3_utils)用来手工发送TUR命令。
UASP:USB Attached SCSI Protocol
vold OBB: Opaque Binary Blob
W-LUNs:UFS Well Known Logical Units

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要让STM32 USB Mass Storage设备与电脑通信,您需要在STM32设备上实现USB Mass Storage设备固件,并将其连接到电脑的USB端口。然后,您可以使用计算机上的文件管理器或其他支持USB Mass Storage协议的应用程序访问STM32设备上的文件系统。您还可以通过USB接口发送和接收数据,以便在STM32设备和计算机之间传输数据。 ### 回答2: 要让STM32 USB Mass Storage设备与电脑通信,首先需要在STM32 MCU上编写相应的固件代码。 1. 首先,在STM32硬件上连接一个USB接口,并将其配置为USB设备模式。可以选择配置的方式包括使用STM32提供的CubeMX软件来生成USB设备库文件或手动配置USB设备模式。 2. 然后,在STM32上编写固件代码来处理USB通信协议。这涉及到设置USB设备描述符,配置USB传输端点等。 3. 在STM32上实现Mass Storage协议。这个协议定义了通信双方之间传输文件和数据的规则。可以使用相应的软件库或编写自己的代码实现。 4. 配置文件系统。STM32 USB Mass Storage设备通常用于存储和传输文件。因此,需要在STM32上配置适当的文件系统,如FAT文件系统。 5. 将STM32插入电脑的USB端口。电脑会检测到STM32设备并加载其驱动程序。 6. 现在,可以在电脑上使用文件管理器或其他USB Mass Storage设备支持的应用程序来访问STM32设备。可以像访问其他USB存储设备一样使用它,如复制、粘贴、删除文件等。 需要注意以下事项: - 确保STM32和电脑之间使用正确的USB电缆连接。 - 在STM32的固件代码中实现正确的错误处理和状态指示,以便能够识别和解决通信问题。 - 根据系统需求,可以为STM32设备添加额外的功能,如读写保护、加密等。 总之,要使STM32 USB Mass Storage设备能够与电脑通信,必须在STM32上实现USB设备模式和Mass Storage协议,并在电脑上正确加载驱动程序。一旦连接成功,就可以像使用其他USB存储设备一样使用STM32设备。 ### 回答3: 要将STM32作为USB Mass Storage Device连接到电脑上进行通信,可以按照以下步骤进行: 1. 首先,需要在STM32的固件中实现USB MSC(Mass Storage Class)功能。这意味着STM32将会被识别为一个可见的USB存储设备。可以使用STM32提供的软件库或者其他第三方库来实现这个功能。 2. 在STM32的固件中,需要实现设备的基本功能,如初始化USB硬件、配置USB端口、配置USB中断等等。这些步骤可以通过参考相关资料或者使用官方提供的示例来完成。 3. 在电脑上,需要安装USB驱动程序。这些驱动程序通常由芯片或者供应商提供。安装驱动程序可以确保电脑能够正确识别并操作STM32作为USB设备。 4. 在电脑上,需要使用支持USB Mass Storage Device的操作系统。大部分现代操作系统都支持USB Mass Storage Device,如Windows、Linux、macOS等。插入STM32到电脑上后,操作系统会自动识别STM32作为USB存储设备。 5. 一旦STM32被识别为USB存储设备,电脑上就可以像操作常规硬盘一样进行读写操作。用户可以通过资源管理器、文件浏览器等工具来访问STM32存储设备,并操作其中的文件和文件夹。 总结起来,要将STM32作为USB Mass Storage Device与电脑通信,关键是在STM32的固件中实现USB MSC功能,并确保在电脑上安装了相关驱动程序和支持USB Mass Storage Device的操作系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值