众所周知存取数据最常见的是以文件方式。每当需要存取数据的时候,首先需要open and creat一个文件,随后read and write,完成后close,清空点格式化,查看文件敲ls/ll;这些看似简单的命令是如何到达disk(disk表示我可不知道命令、文件,我只认识数据)。
一个很明显的需求摆在眼前,我们需要在disk和文件直接建立映射关系。怎么建立?文件系统就是我们建立关系载体,bio就是的手段,disk就是目标。
当我们在windows上插入一张从未使用过的盘片的时候,会出现什么状况?
——请格化
windows怎么知道你没被格式化呢?
——叫你一声没人应
VxWorks面临一样的问题,我初次见到你怎么确定我们是否认识?叫你一声(读引导记录扇区),看你一眼(读文件系统保留区), 问你一句(读空间分配状态和文件/目录存储关系区)。OK,我们看看VxWorks下FAT32是怎么识别盘片的。
发read sector=0 length = 1 bio两次,识别第一个block中的某些字段(0~1BD引导代码、分区表),如果不匹配则初始化它为rawfs,如果匹配则从sector=X开始读大概几百兆(和盘片容量有关,下文解释)的数据,如果其中特定的字段是匹配的,再次读sector=X,这样就代表probe FAT32 成功了,接下来就可以对disk文件操作(cd/ls/creat/rm/copy)了。(经测试在读取数据的时候抹去当前page末的227字节数据也能匹配fs成功,说明文件系统不是比较其中的每次字节都匹配,只对其中特殊的字段作比较)
DOS的外壳---引导记录扇区:
FAT32属于DOS文件系统的一种,那么FAT32的外壳就应该是DOSFS(测试观察dosfs和ntfs 的 第一个扇区的478~493不同)如下为lba = 0 的数据:
{33 c0 8e d0 bc 00 7c 8e c0 8e d8 be 00 7c bf 00 06 b9 00 02 fc f3 a4 50 68 1c 06 cb fb b9 04 00
bd be 07 80 7e 00 00 7c 0b 0f 85 0e 01 83 c5 10 e2 f1 cd 18 88 56 00 55 c6 46 11 05 c6 46 10 00
b4 41 bb aa 55 cd 13 5d 72 0f 81 fb 55 aa 75 09 f7 c1 01 00 74 03 fe 46 10 66 60 80 7e 10 00 74
26 66 68 00 00 00 00 66 ff 76 08 68 00 00 68 00 7c 68 01 00 68 10 00 b4 42 8a 56 00 8b f4 cd 13
9f 83 c4 10 9e eb 14 b8 01 02 bb 00 7c 8a 56 00 8a 76 01 8a 4e 02 8a 6e 03 cd 13 66 61 73 1c fe
4e 11 75 0c 80 7e 00 80 0f 84 8a 00 b2 80 eb 84 55 32 e4 8a 56 00 cd 13 5d eb 9e 81 3e fe 7d 55
aa 75 6e ff 76 00 e8 8d 00 75 17 fa b0 d1 e6 64 e8 83 00 b0 df e6 60 e8 7c 00 b0 ff e6 64 e8 75
00 fb b8 00 bb cd 1a 66 23 c0 75 3b 66 81 fb 54 43 50 41 75 32 81 f9 02 01 72 2c 66 68 07 bb 00
00 66 68 00 02 00 00 66 68 08 00 00 00 66 53 66 53 66 55 66 68 00 00 00 00 66 68 00 7c 00 00 66
61 68 00 00 07 cd 1a 5a 32 f6 ea 00 7c 00 00 cd 18 a0 b7 07 eb 08 a0 b6 07 eb 03 a0 b5 07 32 e4
05 00 07 8b f0 ac 3c 00 74 09 bb 07 00 b4 0e cd 10 eb f2 f4 eb fd 2b c9 e4 64 eb 00 24 02 e0 f8
24 02 c3 49 6e 76 61 6c 69 64 20 70 61 72 74 69 74 69 6f 6e 20 74 61 62 6c 65 00 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 00 4d 69 73 73 69 6e
67 20 6f 70 65 72 61 74 69 6e 67 20 73 79 73 74 65 6d 00 00 00 63 7b 9a 2d 0e df 60 00 00 }引导代码
{
00 -----是否可引导,0不可,0x80可引导
20 21 00 ----分区起始chs
07----分区类型,(不重要,由分区引导决定)
fe ff ff-----分区chs结束地址
00 08 00 00----分区lba地址0x00000800=X(上文中提到的)
00 08 eb 01----分区大小扇区数
}分区表1
下同
{
80
fe ff ff
0c
fe ff ff
00 10 eb 01
00 50 60 02
}分区表2
{
00
feff ff
07
fe ff ff
00 60 4b 04
00 b8 7c 6b
}分区表3
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{55 aa}签名
DOS的外壳FAT的核----FAT保留区:
从上面分区信息可以看到分区起始LBA地址为0x800,这个地址就是FAT保留区,下文为0x800数据:
eb 3e 90 ---汇编指令,跳转到引导代码处
56 58 35 44 4f 53 33 32---文件系统标志
00 02---每个扇区字节数(0x0200)
40---每个block扇区数
20 00 ---保留扇区数
02---FAT表个数
00 00 ---FAT32为0
00 00 ---扇区总数,超过长度存放于0x20~0x23
f8 ---介质描述符
00 00---FAT32为0
d0 9d ---每个此道扇区数
18 00---磁头数
00 08 00 00 ---分区前已用扇区数
00 10 c8 6f ---文件系统扇区总数
41 7e 03 00---每个FAT表大小
00 00 ---标记
00 00---版本号
02 00 00 00----根目录起始block号
01 00 --FSINFO所在扇区号,通常为1号扇区
06 00---备份引导扇区
00 00 00 00 00 00 00 00 00 00 00 00
80 ---bios int 13h设备号
00---
29---扩展引导标识,如果猴年三个值有效则为0x29
00 01 98 07---卷序列号
00 47 01 bd d0 32 b8 45 32 00 00---卷标
46 41 54 33 32 20 20 20 ---文件系统格式
{
00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa
52 52 61 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 72 72 41 61 4c 04 bf 01 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00
}引导代码错误信息
{55 aa}签名
DOS的外壳FAT的核---FAT表:
FAT表描述block分配状态及表明文件和目录的下一个block号。
FAT32每个block地址使用4个字节记录在FAT表中,FAT表中所有的字节位置意4字节对齐,对所有 的划分后的位置由0进行地址编号,0号 1号地址被系统保留并存储特殊的标识内容,从2号地址每个地址对应的数据区的block号当文件系统被创建时,也就是格式化的时候分配给FAT区域的空间将被清空,在FAT1与FAT2的0号表项与1号表项写入特定的值在2号表项写入结束标识。
eg: 看0x820扇区数据:
|——0号—| |——1号—| |——2号—|
f8 ff ff ff ff ff ff f7 ff ff ff 0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
如果某个block未被使用对应的FAT表项4字节为0。
当某个block已被使用对应的FAT表项的4字节为该文件的下一关存储位置的block号。
如果该文件结束于该block,则在它的FAT表项中记录一关文件结束标记0x0fffffff。
如果该扇区为坏扇区记录0x0ffffff7,FAT32的0号表项为0xf8ffff0f。
文件系统建立新文件的时候,如果建立的新文件只占用一个block,则在其所占的FAT表项会被写入结束标记。
DOS的外壳FAT的核---数据区:
根目录一般位于2号block(位于数据区的2号block),用于存放文件基本信息(包括文件名、文件建立时间、修改时间、文件数据等)。
根目录在文件系统创建时创建,并将结束符写入2号block对应的FAT表项。
目录项:文件名部分不足8个字符,用0x20补齐。
1、 获取盘片在位状态
2、 获取盘片容量和blocksize
3、 获取xbd 设备
4、 读sector 0 两次,比较两次读取的数据是否一致
5、 写文件系统引导代码及分区表数据到sector 0、写FAT保留区、写FAT表项。
6、 向盘片发送flush命令
7、 Read sector 0