2011-06-02 22:30:48

FAT32文件系统学习(上)-LMLPHP

目的:需要编写SD读图片的底层驱动程序。所以要了解一个SD卡常用文件系统基本概念。累计学习用时2.5小时。

一,FAT32的保留区

1,引导扇区 :引导扇区是FAT32文件系统的第一个扇区,也称为DBR扇区。它包含这样一些文件系统的基本信息:

【1】 每扇区字节数 【2】 每簇扇区数 【3】 保留扇区数【4】 FAT表个数 【5】 文件系统大小(扇区数)【6】 每个FAT表大小(扇区数) 【7】 根目录起始簇号 【8】 其他一些附加信息

边看说明,边看图片不太方便,我就按照说明内容,把说明直接标注在图片上了。

我的SD卡是手机里的tf卡+sd卡套。之前没有问题。当我第一次格式化后,就发现不正常了。虽然存取文件都没问题。但是放在我的开发板上测试SD的时候,数据显示不正确。

现在我初步发现问题在这里

【13】0x1C~0x1F:4个字节,分区前已使用扇区数,137(0x00 00 00 89)。(这个数据要尤其的重视,文件系统初始化的第一步要找的就是这玩意儿。因为我们的SD卡没有分区,默认就是一个分区,这个数据就是相对于MBR(关于MBR的介绍请读者参看8.4小节的DOC 分区)的地址偏移量,MBR的扇区地址才是整个SD卡的物理扇区号为0的那个地址,也就是说文件系统并不是处在整个SD卡最开始的地方,它处在MBR所处的保留区之后,于是我们可以对使用FAT32文件系统的SD卡整体布局给出如下图示)

FAT32文件系统学习(上)-LMLPHP

但是我0x1C到0x1F的4个字节为0.不知道是不是问题。

2,引导代码

FAT32文件系统引导扇区的512字节中,90~509字节为引导代码,而FAT12/16则是62~509字节为引导代码。同时,FAT32还可以利用引导扇区后的山区空间存放附加的引导代码。

一个FAT卷即使不是可引导文件文件系统,也会存在引导代码。

3,FSINFO信息扇区

FAT32在保留区中增加了一个FSINFO扇区,用以记录文件系统中空闲簇的数量以及下一可用簇的簇号等信息,以供操作系统作为参考。

FSINFO信息扇区结构

省略

温馨提示:通常情况下,文件系统的2号扇区结尾也会被设置“55 AA”标志。6号扇区也会有一个引导扇区的备份,相应的,7号扇区应该是一个备份FSINFO信息扇区。8号扇区可以看做是2号扇区的备份,它的结尾也会有一个“55 AA”标志。

二,FAT32的FAT表

1 FAT表概述

位于保留区后的是FAT区,有两个完全相同的FAT(File Allocation Table, 文件分配表)表组成,FAT文件系统的名字也是因此而来。

重要说明:

1. 对于文件系统来说,FAT表有两个重要作用:描述簇的分配状态以及标明文件或目录的下一簇的簇号。

2. 通常情况下,一个FAT把文件系统会有两个FAT表,但有时也允许只有一个FAT表,FAT表的具体个数记录在引导扇区的偏移0x10字节处。

3. 由于FAT区紧跟在文件系统保留区后,所以FAT1在文件系统中的位置可以通过引导记录中偏移0x0E~0x0F字节处的“保留扇区数”得到。

4. FAT2紧跟在FAT1之后,它的位置可以通过FAT1的位置加上FAT表的大小扇区数计算出来。

2 FAT表的特性

FAT表由一系列大小相等的FAT表项组成,总的说来FAT表有如下特性:

1. FAT32中每个簇的簇地址,是有32bit(4个字节)记录在FAT表中。FAT表中的所有字节位置以4字节为单位进行划分,并对所有划分后的位置由0进行地址编号。0号地址与1号地址被系统保留并存储特殊标志内容。从2号地址开始,每个地址对应于数据区的簇号,FAT表中的地址编号与数据区中的簇号相同。我们称FAT表中的这些地址为FAT表项,FAT表项中记录的值称为FAT表项值。

2. 当文件系统被创建,也就是进行格式化操作时,分配给FAT区域的空间将会被清空,在FAT1与FAT2的0号表项与1号表项写入特定值。由于创建文件系统的同时也会创建根目录,也就是为根目录分配了一个簇空间,通常为2号簇,所以2号簇所对应的2号FAT表项也会被写入一个结束标记。如下图所示:

3. 如果某个簇未被分配使用,它所对应的FAT表项内的FAT表项值即用0进行填充,表示该FAT表项所对应的簇未被分配。

4. 当某个簇已被分配使用时,则它对应的FAT表项内的FAT表项值也就是该文件的下一个存储位置的簇号。如果该文件结束于该簇,则在它的FAT表项中记录的是一个文件结束标记,对于FAT32而言,代表文件结束的FAT表项值为0x0FFFFFFF。

5. 如果某个簇存在坏扇区,则整个簇会用FAT表项值0xFFFFFF7标记为坏簇,不再使用,这个坏簇标记就记录在它所对应的FAT表项中。

6. 由于簇号起始于2号,所以FAT表项的0号表项与1号表项不与任何簇对应。FAT32的0号表项值总是“F8FFFF0F”。如上图所示。

7. 1号表项可能被用于记录脏标志,以说明文件系统没有被正常卸载或者磁盘表面存在错误。不过这个值并不重要。正常情况下1号表项的值为“FFFFFFFF”或“FFFFFF0F”。

8. 在文件系统中新建文件时,如果新建的文件只占用一个簇,为其分配的簇对应的FAT表项将会写入结束标记。如果新建的文件不只占用一个簇,则在其所占用的每个簇对应的FAT表项中写入为其分配的下一簇的簇号,在最后一个簇对应的FAT表象中写入结束标记。

9. 新建目录时,只为其分配一个簇的空间,对应的FAT表项中写入结束标记。当目录增大超出一个簇的大小时,将会在空闲空间中继续为其分配一个簇,并在FAT表中为其建立FAT表链以描述它所占用的簇情况。

10. 对文件或目录进行操作时,他们所对应的FAT表项将会被清空,设置为0以表示其所对应的簇处于未分配状态。

要找一个簇的FAT表项,只要用它的簇号乘以每个FAT表项的字节数即可。Winhex提供了直接跳转到某个指定FAT表项的功能,单击position|go to FAT Entry,即可弹出转到FAT项对话框,在对话框输入目标FAT项号码后单击OK,光标即会在该FAT项的第一个字节上闪烁。

看到这里,我明白了簇地址就是一个大文件,被拆分成小块后的一个个个像链表一样的地址。保存在FAT表中。

今天主要看了保留区和FAT表区。明天继续看数据区。

04-01 01:02