分享

FAT32文件格式示例解析

 sdxy 2019-10-29

1.前言

本文主要以一个示例来分析FAT32文件系统的格式,对FAT32文件系统的各个区域详细分析。

2.FAT32文件系统典型分区

3.FAT32文件系统示例

按如下步骤在ubuntu下创建FAT32文件系统:

1.chenbo@chenbo-ThinkPad-R61:~$ cd /tmp/

2.创建文件test.img

chenbo@chenbo-ThinkPad-R61:/tmp$ sudo dd if=/dev/zero of=test.img bs=512 count=80000

3.创建FAT32文件系统

chenbo@chenbo-ThinkPad-R61:/tmp$ sudo mkfs.vfat -F 32 test.img

4.将test.img挂载在/mnt

chenbo@chenbo-ThinkPad-R61:/tmp$ sudo mount test.img /mnt

5.创建test1 test2 test3三个目录

chenbo@chenbo-ThinkPad-R61:/mnt$ sudo mkdir test1 test2 test3

6.在test1下创建test1-1   test1-1-1目录

chenbo@chenbo-ThinkPad-R61:/mnt$ cd test1

chenbo@chenbo-ThinkPad-R61:/mnt/test1$ sudo mkdir test1-1

chenbo@chenbo-ThinkPad-R61:/mnt/test1$ cd test1-1/

chenbo@chenbo-ThinkPad-R61:/mnt/test1/test1-1$ sudo mkdir test1-1-1

7.创建hello.txt文件,写入内容,拷贝到test1/test1-1/test1-1-1下

chenbo@chenbo-ThinkPad-R61:/tmp$ touch hello.txt

chenbo@chenbo-ThinkPad-R61:/tmp$ echo you are my friend! > hello.txt

chenbo@chenbo-ThinkPad-R61:/tmp$ sudo cp hello.txt /mnt/test1/test1-1/test1-1-1/

8.执行完如上步骤后,通过hexdump查看文件系统内容

chenbo@chenbo-ThinkPad-R61:/tmp$ sudo umount /mnt

chenbo@chenbo-ThinkPad-R61:/tmp$ hexdump -C test.img

00000000  eb 58 90 6d 6b 66 73 2e  66 61 74 00 02 01 20 00  |.X.mkfs.fat... .|

00000010  02 00 00 00 00 f8 00 00  20 00 40 00 00 00 00 00  |........ .@.....|

00000020  80 38 01 00 68 02 00 00  00 00 00 00 02 00 00 00  |.8..h...........|

00000030  01 00 06 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00000040  80 00 29 80 73 bc 92 4e  4f 20 4e 41 4d 45 20 20  |..).s..NO NAME  |

00000050  20 20 46 41 54 33 32 20  20 20 0e 1f be 77 7c ac  |  FAT32   ...w|.|

00000060  22 c0 74 0b 56 b4 0e bb  07 00 cd 10 5e eb f0 32  |".t.V.......^..2|

00000070  e4 cd 16 cd 19 eb fe 54  68 69 73 20 69 73 20 6e  |.......This is n|

00000080  6f 74 20 61 20 62 6f 6f  74 61 62 6c 65 20 64 69  |ot a bootable di|

00000090  73 6b 2e 20 20 50 6c 65  61 73 65 20 69 6e 73 65  |sk.  Please inse|

000000a0  72 74 20 61 20 62 6f 6f  74 61 62 6c 65 20 66 6c  |rt a bootable fl|

000000b0  6f 70 70 79 20 61 6e 64  0d 0a 70 72 65 73 73 20  |oppy and..press |

000000c0  61 6e 79 20 6b 65 79 20  74 6f 20 74 72 79 20 61  |any key to try a|

000000d0  67 61 69 6e 20 2e 2e 2e  20 0d 0a 00 00 00 00 00  |gain ... .......|

000000e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|

00000200  52 52 61 41 00 00 00 00  00 00 00 00 00 00 00 00  |RRaA............|

00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

000003e0  00 00 00 00 72 72 41 61  89 33 01 00 08 00 00 00  |....rrAa.3......|

000003f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|

00000400  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

00000c00  eb 58 90 6d 6b 66 73 2e  66 61 74 00 02 01 20 00  |.X.mkfs.fat... .|

00000c10  02 00 00 00 00 f8 00 00  20 00 40 00 00 00 00 00  |........ .@.....|

00000c20  80 38 01 00 68 02 00 00  00 00 00 00 02 00 00 00  |.8..h...........|

00000c30  01 00 06 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00000c40  80 00 29 80 73 bc 92 4e  4f 20 4e 41 4d 45 20 20  |..).s..NO NAME  |

00000c50  20 20 46 41 54 33 32 20  20 20 0e 1f be 77 7c ac  |  FAT32   ...w|.|

00000c60  22 c0 74 0b 56 b4 0e bb  07 00 cd 10 5e eb f0 32  |".t.V.......^..2|

00000c70  e4 cd 16 cd 19 eb fe 54  68 69 73 20 69 73 20 6e  |.......This is n|

00000c80  6f 74 20 61 20 62 6f 6f  74 61 62 6c 65 20 64 69  |ot a bootable di|

00000c90  73 6b 2e 20 20 50 6c 65  61 73 65 20 69 6e 73 65  |sk.  Please inse|

00000ca0  72 74 20 61 20 62 6f 6f  74 61 62 6c 65 20 66 6c  |rt a bootable fl|

00000cb0  6f 70 70 79 20 61 6e 64  0d 0a 70 72 65 73 73 20  |oppy and..press |

00000cc0  61 6e 79 20 6b 65 79 20  74 6f 20 74 72 79 20 61  |any key to try a|

00000cd0  67 61 69 6e 20 2e 2e 2e  20 0d 0a 00 00 00 00 00  |gain ... .......|

00000ce0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

00000df0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|

00000e00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

00004000  f8 ff ff 0f ff ff ff 0f  f8 ff ff 0f ff ff ff 0f  |................|

00004010  ff ff ff 0f ff ff ff 0f  ff ff ff 0f ff ff ff 0f  |................|

00004020  ff ff ff 0f 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00004030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

00051000  f8 ff ff 0f ff ff ff 0f  f8 ff ff 0f ff ff ff 0f  |................|

00051010  ff ff ff 0f ff ff ff 0f  ff ff ff 0f ff ff ff 0f  |................|

00051020  ff ff ff 0f 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00051030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

0009e000  41 74 00 65 00 73 00 74  00 31 00 0f 00 2e 00 00  |At.e.s.t.1......|

0009e010  ff ff ff ff ff ff ff ff  ff ff 00 00 ff ff ff ff  |................|

0009e020  54 45 53 54 31 20 20 20  20 20 20 10 00 00 ba 23  |TEST1      ....#|

0009e030  4d 4c 4d 4c 00 00 ba 23  4d 4c 03 00 00 00 00 00  |MLML...#ML......|

0009e040  41 74 00 65 00 73 00 74  00 32 00 0f 00 9a 00 00  |At.e.s.t.2......|

0009e050  ff ff ff ff ff ff ff ff  ff ff 00 00 ff ff ff ff  |................|

0009e060  54 45 53 54 32 20 20 20  20 20 20 10 00 00 a1 23  |TEST2      ....#|

0009e070  4d 4c 4d 4c 00 00 a1 23  4d 4c 04 00 00 00 00 00  |MLML...#ML......|

0009e080  41 74 00 65 00 73 00 74  00 33 00 0f 00 76 00 00  |At.e.s.t.3...v..|

0009e090  ff ff ff ff ff ff ff ff  ff ff 00 00 ff ff ff ff  |................|

0009e0a0  54 45 53 54 33 20 20 20  20 20 20 10 00 00 a1 23  |TEST3      ....#|

0009e0b0  4d 4c 4d 4c 00 00 a1 23  4d 4c 05 00 00 00 00 00  |MLML...#ML......|

0009e0c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

0009e200  2e 20 20 20 20 20 20 20  20 20 20 10 00 00 a1 23  |.          ....#|

0009e210  4d 4c 4d 4c 00 00 a1 23  4d 4c 03 00 00 00 00 00  |MLML...#ML......|

0009e220  2e 2e 20 20 20 20 20 20  20 20 20 10 00 00 a1 23  |..         ....#|

0009e230  4d 4c 4d 4c 00 00 a1 23  4d 4c 00 00 00 00 00 00  |MLML...#ML......|

0009e240  41 74 00 65 00 73 00 74  00 31 00 0f 00 a7 2d 00  |At.e.s.t.1....-.|

0009e250  31 00 00 00 ff ff ff ff  ff ff 00 00 ff ff ff ff  |1...............|

0009e260  54 45 53 54 31 2d 31 20  20 20 20 10 00 64 c3 23  |TEST1-1    ..d.#|

0009e270  4d 4c 4d 4c 00 00 c3 23  4d 4c 06 00 00 00 00 00  |MLML...#ML......|

0009e280  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

0009e400  2e 20 20 20 20 20 20 20  20 20 20 10 00 00 a1 23  |.          ....#|

0009e410  4d 4c 4d 4c 00 00 a1 23  4d 4c 04 00 00 00 00 00  |MLML...#ML......|

0009e420  2e 2e 20 20 20 20 20 20  20 20 20 10 00 00 a1 23  |..         ....#|

0009e430  4d 4c 4d 4c 00 00 a1 23  4d 4c 00 00 00 00 00 00  |MLML...#ML......|

0009e440  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

0009e600  2e 20 20 20 20 20 20 20  20 20 20 10 00 00 a1 23  |.          ....#|

0009e610  4d 4c 4d 4c 00 00 a1 23  4d 4c 05 00 00 00 00 00  |MLML...#ML......|

0009e620  2e 2e 20 20 20 20 20 20  20 20 20 10 00 00 a1 23  |..         ....#|

0009e630  4d 4c 4d 4c 00 00 a1 23  4d 4c 00 00 00 00 00 00  |MLML...#ML......|

0009e640  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

0009e800  2e 20 20 20 20 20 20 20  20 20 20 10 00 00 ba 23  |.          ....#|

0009e810  4d 4c 4d 4c 00 00 ba 23  4d 4c 06 00 00 00 00 00  |MLML...#ML......|

0009e820  2e 2e 20 20 20 20 20 20  20 20 20 10 00 00 ba 23  |..         ....#|

0009e830  4d 4c 4d 4c 00 00 ba 23  4d 4c 03 00 00 00 00 00  |MLML...#ML......|

0009e840  41 74 00 65 00 73 00 74  00 31 00 0f 00 0e 2d 00  |At.e.s.t.1....-.|

0009e850  31 00 2d 00 31 00 00 00  ff ff 00 00 ff ff ff ff  |1.-.1...........|

0009e860  54 45 53 54 31 2d 7e 31  20 20 20 10 00 64 45 24  |TEST1-~1   ..dE$|

0009e870  4d 4c 4d 4c 00 00 45 24  4d 4c 07 00 00 00 00 00  |MLML..E$ML......|

0009e880  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

0009ea00  2e 20 20 20 20 20 20 20  20 20 20 10 00 64 c3 23  |.          ..d.#|

0009ea10  4d 4c 4d 4c 00 00 c3 23  4d 4c 07 00 00 00 00 00  |MLML...#ML......|

0009ea20  2e 2e 20 20 20 20 20 20  20 20 20 10 00 64 c3 23  |..         ..d.#|

0009ea30  4d 4c 4d 4c 00 00 c3 23  4d 4c 06 00 00 00 00 00  |MLML...#ML......|

0009ea40  41 68 00 65 00 6c 00 6c  00 6f 00 0f 00 f1 2e 00  |Ah.e.l.l.o......|

0009ea50  74 00 78 00 74 00 00 00  ff ff 00 00 ff ff ff ff  |t.x.t...........|

0009ea60  48 45 4c 4c 4f 20 20 20  54 58 54 20 00 64 45 24  |HELLO   TXT .dE$|

0009ea70  4d 4c 4d 4c 00 00 45 24  4d 4c 08 00 13 00 00 00  |MLML..E$ML......|

0009ea80  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

0009ec00  79 6f 75 20 61 72 65 20  6d 79 20 66 72 69 65 6e  |you are my frien|

0009ec10  64 21 0a 00 00 00 00 00  00 00 00 00 00 00 00 00  |d!..............|

0009ec20  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*

027100004

4.示例解析

对如上创建的文件系统进行解析如下。

4.1 保留区

4.1.1 BPB和启动扇区

启动跳转:本身占2字节它将程序执行流程跳转到引导程序处。

OEMNAME:这部分占8字节,其内容由创建该文件系统的OEM厂商具体安排。

详细参数请参见:FAT文件系统规范v1.03学习笔记---1.保留区之启动扇区与BPB

4.1.2 引导程序

引导程序代码:FAT32的DBR引导程序占用420字节,对于没有安装操作系统的分区来说这段程序是没有用处的。

结束标志:为“55 AA”

4.1.3 FSInfo区

FAT32文件系统在保留区中安排了一个文件系统信息扇区,用以记录数据区中空闲簇的数量及下一个空闲簇的簇号,该扇区一般在分区的1号扇区,也就是紧跟着BPB和启动扇区后的一个扇区

详细请参见:FAT文件系统规范v1.03学习笔记---1.保留区之 Fat32 FSInfo扇区结构和备份启动扇区

4.1.4 BPB与启动扇区备份

4.1.5 保留区之剩余部分空间

4.2 FAT区

FAT区一般为两个,用于备份。对于FAT32每4个字节表示一簇,用来表示簇的状态。由BPB分区中FATsz32可知FAT区大小为0x0268个也就是616个扇区。

FAT表结构及作用

(1)FAT32文件一般有两份FAT,他们由格式化程序在对分区进行格式化时创建,FAT1是主,FAT2是备份。

(2)FAT1跟在保留分区之后,其具体地址由BPB参数中指定,FAT2跟在FAT1的后面。

(3)FAT表由FAT表项构成,我们把FAT表项简称FAT项,每个FAT项占用4字节。

(4)每个FAT项都有一个固定的编号,这个编号从0开始。

(5)FAT表项的前两个FAT项为文件系统保留使用,0号FAT为介质类型,1号FAT为文件系统错误标志。

(6)分区的数据区中每个簇都会映射到FAT表中的唯一一个FAT项,因为0号FAT和1号FAT被系统占用,用户的数据从2号FAT开始记录。

(7)如果某个文件占用很多个簇,则第一个FAT项记录下一个FAT项的编号(既簇号),如果这个文件结束了,则用“0F FF FF FF”表示。

(8)分区格式化后,用户文件以簇为单位存放在数据区中,一个文件至少占用一个簇。

(9)FAT的主要作用是标明分区存储的介质以及簇的使用情况

定位FAT绝对位置的方法

(1)首先从MBR的分区表中得知分区的起始扇区,偏移到此扇区(我的是单分区,没有分区表?)。

(2)从DBR的BPB中得知DBR的保留扇区数,FAT表的个数,FAT表的大小。

(3)因此FAT1=分区起始扇区+保留扇区数,FAT2=分区起始扇区+保留扇区数+FAT1大小。

4.3 文件与目录数据区

由于0号簇和1号簇用于特殊用途,实际目录和文件是从2号簇开始存放

由hello.txt目录项可知它的内容存储在0x00000008的簇(8号簇)里面,如下图:

再去回看前面FAT区中8号簇的状态为0ffffffff,表示这是最后一个簇

数据区的定位方式

数据区的位置在FAT2的后面,具体定位方式如下;

(1)通过MBR中的分区表信息得知分区的起始位置。

(2)通过分区中BPB保留扇区数以及FAT表的大小,FAT表的个数。

(3)通过上面的信息就可以找到数据区的起始位置,根目录=数据区的起始扇区+(簇大小*2)。

数据区分类

数据区的内容主要由三部分组成:根目录,子目录和文件内容。在数据区中是以“簇”为单位进行存储的,2号簇被分配给根目录使用。

根目录的定位方式

根目录=分区起始扇区+DBR保留扇区+(FAT表*2)+(簇大小*2)

FAT32文件系统中,分区根目录下的文件和目录都放在根目录区中,子目录中的文件和目录都放在子目录区中,并且没每32个字节为一个目录项,

每个目录项纪录着一个目录或文件(也可能是多个目录项记录一个文件或目录)

目录项分类

在FAT32文件系统中,目录项可以分为四类:卷标目录项、“.”和“..”目录项、短文件名目录项、长文件名目录项

(1)卷标目录项:卷标就是分区的名字,可以在格式化分区时创建,也可以随意修改,长度为11字节。

(2)“.”和“..”目录项:“.”表示当前目录,“..”表示上一层目录。这两个目录项多存在子目录中。

(3)短文件名目录项:所谓短文件名既文件名的“8.3”格式,此格式支持主文件名不能超过8字节,扩展名不能超过3字节。短文件名目录始终存放在一个目录项中。

(4)长文件名目录项:由于短文件名“8.3”的格式远远不能满足现实中的需求,所以就出现了长文件名,长文件名其实就是将文件名进行分段,分成若干个短文件名进行存储。

长文件名处理原则

(1)系统取长文件名的前6个字符加上“~1”形成短文件名,其扩展名不变;

(2)如果已存在这个名字的文件,则符号“~”后的数字自动增加;

(3)如果文件名内存在windows非法的字符,则以下划线“_”代替;

(4)长文件名目录项采用倒叙的方式进行记录。

FAT32文件系统

这是一个FAT32文件系统,FAT1=FAT2,每一个簇占一项,内容是下一个簇号,如果是某一个文件的最后一个簇,那么内容为FFFFFF0F;

淡绿色的里面就是目录和文件了。

这些用来存放所有文件和文件夹的“簇”占据着硬盘大部分的空间。簇是从2号开始的,所以没有0号和1号簇。如果你需要访问特定的簇,你需要用以下这条公式吧簇号(cluster number)转换为IDE设备的LBA地址:

  通常,簇的大小最少为4K(8个扇区),8K,16K和32K的簇很少使用。一些新版本的Microsoft Windows系统允许使用更 大的簇,而处于对效率的考虑,扇区(簇?)的大小都是512字节的倍数。Microsoft指出,FAT32描述的文件系统最大的簇大小为32K。

现在只要我们知道文件在哪里……

刚开始时,你只知道第一个簇和根目录(Root directory)的地址。读取目录将可以知道其他文件和目录的名字和起始簇在哪里。很重要的一点是:目录仅仅告诉你怎么找到文件和子目录的起始的簇在哪里。你还需要从目录中获取诸如文件长度、修改时间、文件属性等其他种类的信息。但是目录只会告诉你文件在哪里。要得到起始簇以外的信息,你需要用到FAT(文件分配表)。但首先你需要找到这些文件是从哪里开始的。

在这节里面,我们只会简短地看看目录,知道哪些是找到文件所必须的。然后我们将看看怎么通过文件分配表(FAT)来找到剩下的文件。最后我们将来回头看看关于目录结构的细节。

目录数据被组织成32个字节的记录。这很好,因为每一个扇区刚好可以保存16条记录,没有记录会卡在扇区与扇区中间。这里有四种32个字节的目录记录:

短文件名的普通记录 - 属性是普通

长文件名文本 - 属性含有全部的4个字节

未使用 - 第一个字节为0xE5

目录结尾 - 第一个字节为0x00

未使用的目录记录可能是被删除的文件的记录,它的第一个字节被0xE5覆盖掉,当有新文件被创建时就可以重新使用这条记录。目录的最后是一条开头第一个字节为0的记录。所有其他的记录都是以非0开头的,所以可以很容易的察觉到你什么时候到达了目录的结尾。

属性字(Attrib byte)通过6bits来决定,具体如下表所示。大多数程序框架都是通过检查属性字来决定这32个字节是一般目录记 录还是长文件名数据,以及决定他是一个普通文件还是子目录。长文件名记录会把最后4位置为1。普通的文件很少会把这最后四个位全部置为1。

剩下的区域就相对简单和直接。开头11字节是短文件名(旧8.3格式-old 8.3 format)。扩展功能允许使用其后面的3个字节。 如果文件名的长度小于8字节,剩下的字节就会用0x20填充。起始簇号码被分为两个16位来储存,以及最后4个字节用来储存文件的大小。这两者的储存都是 通过字节来存取,低位在前,高位在后。起始簇号码告诉我们文件的数据从硬盘的哪里开始,文件大小告诉我们这个文件有多长。由于硬盘的实际空间都是通过整数 个簇来分配的,所以文件大小会让你知道其后的多少个簇存放着文件的数据。

文件分配表(File Allocation Table) - 连成链的簇

目录的入口告诉你文件或子目录的起始簇在硬盘的什么地方,然后就理所当然的从卷ID中的根目录中找到了第一个簇。对于小文件和目录 (大小在一个簇以内),你能从文件分配表(FAT)得到的信息只是:这个文件不占用更多的簇。要访问剩下超过一个簇的文件时,你就需要使用文件分配表 (FAT)。FAT32这个名字所代表的含义是表格中每一个入口(entry)都是32位的。在FAT16和FAT12中,入口时16和12位的。 FAT16和FAT12的工作方式与FAT32相同(只是令人讨厌的是12位的入口经常对齐不了扇区的边界,但是16和32位的入口是不会超出扇区边界 的)。我们将只介绍FAT32。

文件分配表是一个很大的32位整数序列。这个序列中的每一个入口(32位)在序列中的位置对应簇的号码,而每个入口中的内容储存着的 是该文件下一个簇的位置。文件分配表的目的就是在你知道目前簇的位置时,告诉你下一个簇的位置在哪里。每一个扇区中包含有128个这种32位的整数,所以 可以相对简单地知道下一个簇的位置。当前所在的入口中,第7到31位告诉你下一个入口在FAT中的那个扇区,剩下的0到6位告诉你下一个入口是这个扇区中 128个入口的哪一个(如果所有位都置为1,说明这是文件的结尾)。

这是一个虚拟的例子,里面有三个小文件和根目录,他们都分布在第一个簇的附近(下图中,文件需要的所有簇号码画在FAT图的旁边)。 注意到,下面这个根目录占用了5个簇,但是却悲剧的仅仅含有三个文件。这里只是想展示一下怎么样链式的寻找到簇。但是值得注意的是,如果是小的根目录(只 占一个簇),表中第2个入口中的内容将是“FFFFFFFF”(在卷ID中包含了根目录簇的首地址),而不是通过“00000009”号到达其他的簇。然 而,当根目录有很多文件的情况下,根目录会占用几个簇,但是这几个簇很少会连在一起,毕竟在你存入更多的文件之前,这个根目录还是一个只占用一个簇的小目 录。那么在记住这些要点后,我们来看看简单的例子:

图7:FAT32扇区,根目录和三个文件的簇链

在这个例子中,通过卷ID的信息我们知道根目录从2号簇开始。在FAT的第2个位置里面的数字式9,所以下一个是9号簇。像这样,簇 A,B和11保存了根目录剩下的数据。在位置11的数字“FFFFFFFF”表示这里是根目录的最后一个簇。但是你的代码可能不会去读地11个位置,因为 你将会找到一个目录结束标记(end-of-directory marker)(开头32个字节全为0)。就这样,这个文件系统就含有大小为一个簇的小 型根目录,而且在读取目录时不需要使用FAT,因为只有一个簇。但是如果你在这个簇中没有发现目录结束标记,那么就必须通过FAT来寻找剩下的簇了。

同样的,这里显示了三个文件。在所有情况下,FAT都没有指出哪个是文件的第一个簇,所以必须从目录中提取文件的首地址,然后通过 FAT来访问剩下的簇。分配给文件的簇的总字节数必须大于目录记录中文件大小区域指出的文件大小。除非文件的大小不是簇的整数倍的话,否则最后一个簇的末 尾就会有一部分未使用的空间。文件大小是0的文件将不会分配簇,在目录记录中的簇数量应该为0。文件大小只占用一个簇的文件在FAT中对应簇的内容为 “FFFFFFFF”表示已经到文件末尾。

便捷提示: 一个能使代码尽可能简单的方法是是的根目录非常小(少量文件,只用8.3短文件名),避免出现子目录,以及在电脑上运行整理磁盘碎片程序。这样,根目录能 在一个簇中找到,然后每个文件占据着地址连续的簇。虽然这种实现的功能非常有限,但是这样你就可以不使用文件分配表了。

更具Microsoft的描述,簇号码其实只占28位,高四位是保留的。你可以在把这些保留的位清零。同样的,文件结束号码 (end-of-file number)实际上是所有比0xFFFFFFF8大的数,但是实际上通常使用0xFFFFFFFF。FAT中为全0的标记是 自由的位置。同样的,请记住在内存中簇号码是先储存他们的低字节(低地址对低地址)(图7中使用的格式是为了便于我们阅读,但是他们实际上市先储存低字节 的-stored LSB first)。所以其实在内存中,FAT中二号簇实际上在二进制编码器中会写成“90000000”,低字节在前。

好消息是,对于固件开发者来说使用FAT是很简单的。但是,FAT的简单导致的大量计算往往也是起作为一个通用文件系统的弱点。例 如,为了向文件增加数据,文件系统必须读便整个簇链。在文件中任意位置中定位也需要大量的读取FAT。处于比较的目的,Unix文件系统使用树状结构。其 中的簇(也叫作“区块”)会拥有完整的区块列表(在unix哲学中被叫做“inode”)或者拥有另一个包含着inode的区块。制这种方式下,定位一个 硬盘中的任意一个区块只需要读取1,2或者3个inode。FAT的另外可以通过缓存来缓解的缺点在于,它数据的物理分布会集中在磁盘的“开头”,而不是 分布式储存的。Unix基于inode(inode-based)的文件系统会把inode区块均匀地分布在数据区块之间,然后把数据区块定位在 inode区块附近。

FAT32 FAT区__FAT表解析

一、 FAT 表概述

位置:紧跟在文件系统的“保留区”之后 ; 有两个数据结构完全相同的FAT(FAT,File Allocation Tbale 文件分配表)组成。

作用:FAT表项,描述文件系统内的簇分配状态,说明文件系统内数据所分配的连续簇的顺序关系(即表明文件或目录的下一簇的序号)。

常规规则:

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

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

· FAT2 紧跟在FAT1之后, 它的位置可以通过FAT1的位置加上每个FAT 表的大小扇区数获得。

FAT 表中记录了每个文件的簇链结构;FAT 表中记录的与数据区簇对应的表项,从0号标记开始至当前数据区所分配的簇的最大数值,记录簇信息到FAT 项;但是注意:其中 0号~1号簇的值都是操作系统预先不留设定的特殊标记,而数据区的起始簇是2号簇。

二、、FAT 表的特性

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

· FAT32 中每个簇的状态,使用32bit(4字节)记录在FAT表中。 FAT 表中的所有字节位置以 4个字节为单位进行划分;并以所有划分后的位置由0进行地址编号。“0号 和 1号” 地址被系统保留并存储特殊标识内容。从 2号 地址开始,每个地址对应于数据区的簇号,FAT 表中的地址编号与数据区中的簇号相同。称FAT 中的这些四字节一组划分的项的地址为 FAT 表项 FAT表项中记录的值为FAT 表项值。(簇编号与簇内内容关系如果 Map中的键-值 关系相同)

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

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

· 当某个簇被分配使用时,那么他所对应的FAT表项的值为文件的下一个存储文件的簇号。如果该文件结束于该簇,则在它的FAT表项中记录的是一个文件结束标记,对于FAT32 而言,代表文件结束的FAT表项值为0x0FFFFFFF。

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

· 由于簇号起始于2, 所以FAT表的0号表项与1号表项不予任何簇对应。FAT32 的0号表项值总是“F8FFFF0F”

注意: 可以搜索扇区偏移0字节处的该值(F8FFF0F)以查找FAT表。

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

项内容填写规则:

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

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

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

三、 FAT表的使用

一个文件的“起始簇号”记录在它的目录项中, 该文件的“其他簇”则用一个簇连结构记录在FAT 表中。

如果一个簇所对应的FAT表项的表项值为非零,则表明该簇已经被分配使用了,但是这时表项值可能为两种情况,一个是一个文件的下一个簇号值,也有可能是一个文件的结束标记0x0FFFFFFF,或者是一个坏簇标记0x0FFFFFF7 。

如果要寻找一个文件的下一个簇,只需要查看该文件的目录项中描述的起始簇号所对应的FAT项,如果该文件只有一个簇,则此处的值为一个结束标记0x0FFFFFFF;如果该文件不只一个簇,则此处 的值是它的下一个簇的簇号。

>> 查询簇连接结构模拟步骤:

当我们要寻找某个文件时, 首先从该文件的“目录项”中获取该文件的第一“簇”的簇号,然后根据“第一簇”的“簇号 N”,然后根据N 从FAT区的FAT表找出N簇号所对应的FAT 表项,查看FAT 表项的内容:

若是文件结束,该表项值为 0x0FFFFFFF; 若是没有结束,而该文件的大小超出一个簇,则N所对应的FAT表项的表项值为该文件下一个簇的簇号,然后再找到下一个簇号N+1 所对应的FAT表项,查看其表项值,依次类推,就推出了一个文件在FAT表中的 簇链连接结构; 也或者表项值为 0xFFFFFFF7 坏簇标识。

>> 其他

查找FAT 表项: 要找到一个簇的FAT 表项,只要用他的 簇号乘以每个FAT 表项的字节数即可 。对于FAT32而言,每个FAT 表项占用4个四字节, 如果我们寻找9号簇的表项位置,则用 4*9=36,也就是说位于FAT 表内偏移36(0x24)字节处。

注意:

WinHex 提供了直接跳转到某个指定FAT 表项的功能。

文件系统大小的上限值却绝育FAT 项的大小。 簇链中的每个FAT 项记录着下一个簇的簇地址,FAT 项所能表示的数字有一个上限,这个上限也就是文件系统中的最大簇号。FAT 32文件系统的FAT 项只使用了32bit 中的28bit ,因此只能描述 268435456个簇(实际上还要考略小于这个值,因为这其中还包含了结束标志及坏簇标志的保留值)。

操作系统通过检测FAT 表中的表项来确定文件系统中的各个簇是否被分配使用。当我们在Windows 下右击某个FAT 分区查看其属性时,显示的已用空间和未用空间就是根据FAT 表统计而来的。

有时我们会遇到,查看属性时发现已用空间并没有减少,但存储的文件却不见了。这是因为某些病毒在某些文件的目录项中写入了删除标记,但并没有清楚FAT 表内的簇链所至。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多