USB MSC
主机(如电脑)识别USB MSC(Mass Storage Class)设备中的文件,本质上是通过多层协议协作实现的,涉及USB枚举、SCSI命令传输和文件系统解析三个核心环节。以下是详细机制:
🔍 一、USB枚举:设备身份识别(主机→设备)
当USB MSC设备(如U盘)插入主机时,主机通过USB协议进行设备枚举:
- 设备描述符获取
- 主机请求设备描述符(
Device Descriptor
),确认设备类型(bDeviceClass=0x00
,接口类为MSC)。 - 关键字段:
bInterfaceClass=0x08
(MSC类)、bInterfaceSubClass=0x06
(SCSI指令集)、bInterfaceProtocol=0x50
(Bulk-Only传输协议)。
- 主机请求设备描述符(
- 配置与端点激活
- 主机获取配置描述符,分配端点(Bulk-In/Bulk-Out端点用于数据传输),完成USB通信通道建立。
✅ 此阶段目标:主机确认设备是USB MSC设备,并准备好SCSI命令传输通道。
⚙️ 二、SCSI命令交互:读取存储结构(主机→设备)
主机通过SCSI命令集访问存储介质结构,核心命令包括:
SCSI命令 | 操作码 | 功能 | 返回信息 |
---|---|---|---|
INQUIRY | 0x12 | 查询设备基本信息(厂商、产品型号) | 设备属性、兼容性 |
READ CAPACITY | 0x25 | 获取存储容量(总扇区数、扇区大小) | 容量参数(如512字节/扇区) |
REQUEST SENSE | 0x03 | 获取错误状态(用于异常处理) | 错误代码 |
READ(10) | 0x28 | 读取指定逻辑块地址(LBA)的数据 | 扇区原始数据 |
关键步骤:
- 读取MBR(主引导记录)
- 主机发送
READ(10)
命令,LBA=0,读取磁盘第一个扇区(512字节)。 - MBR包含分区表(64字节),记录分区起始LBA、大小及文件系统类型(如FAT32/NTFS)。
- 主机发送
- 读取DBR(DOS引导记录)
- 根据MBR的分区表,主机定位到分区起始扇区(如LBA=2048),再次发送
READ(10)
读取DBR。 - DBR的BPB(BIOS参数块) 包含文件系统关键参数:
bpbResSectors
:保留扇区数(FAT表之前的扇区数)bpbFATsecs
:每个FAT表大小(扇区数)bpbRootEntCnt
:根目录条目数(FAT32中为0)。
- 根据MBR的分区表,主机定位到分区起始扇区(如LBA=2048),再次发送
📂 三、文件系统解析:定位文件(主机操作系统)
主机操作系统(如Windows/Linux)根据DBR参数解析文件系统:
- 定位FAT表与根目录
- FAT1起始扇区 = 分区起始LBA + 保留扇区数(
bpbResSectors
)。 - 根目录起始扇区(FAT32) = FAT1起始扇区 + FAT表数量 × 每个FAT表大小。
- FAT1起始扇区 = 分区起始LBA + 保留扇区数(
- 遍历目录条目
- 根目录的每个条目(32字节)包含:
- 文件名(8.3格式或长文件名)
- 文件属性(目录/文件/隐藏)
- 起始簇号
- 文件大小。
- 根目录的每个条目(32字节)包含:
- 文件内容读取
- 根据起始簇号,在FAT表中查找簇链,通过
READ(10)
命令读取连续簇的数据。
- 根据起始簇号,在FAT表中查找簇链,通过
🌰 示例:读取
test.txt
文件:
- 根目录找到条目,获起始簇号=2。
- 查FAT表:簇2→簇3→簇4(链式存储)。
- 计算簇2的LBA = 数据区起始LBA + (簇号-2) × 每簇扇区数。
- 发送
READ(10)
读取对应扇区。
💎 总结:主机识别文件的完整流程
[USB设备插入]
[USB枚举:获取描述符]
[激活Bulk端点]
[SCSI命令传输]
[INQUIRY:设备信息]
[READ CAPACITY:容量]
[READ(10)读取MBR/DBR]
[解析文件系统参数]
[定位FAT表/根目录]
[遍历目录条目]
[按簇链读取文件数据]