分类:
2012-09-05 10:59:33
原文地址:FAT32文件系统分析 作者:zyd_cu
FAT文件系统分为三个部分:保留区、FAT区和数据区,如下所示:
|--- 保留区 ---|--- FAT1 ---|--- FAT2 ---|--- 数据区 ---|
1. 保留区中包含文件系统的一些总体信息,类似于unix文件系统里的超级块信息。
2. FAT区包含文件的分配表链。
3. 数据区存放实际的文件数据(目录的数据为目录项列表)。
本人电脑C盘的空间约为40G,簇大小为32k(簇类似于unix文件系统里的块),通过WinHex工具可以查看文件系统信息,以下为C盘上FAT32文件系统DBR(DOS BOOT SECTOR)的信息,主要包括每个扇区字节数(512),每个簇的扇区数(64,32K的簇),保留扇区数(34),FAT表的个数(2),文件系统扇区数(81931392)及没FAT表扇区数(9999)等。
保留区中还包括DBR的备份扇区,FSINFO(记录文件系统中空闲簇数量以及下一个可用簇号灯信息)扇区,保留区后面为FAT区(2个,内容一样),根据保留扇区个数,可以计算出FAT1开始于0x4400(34*512)。
FAT表用于组织文件的分配信息,以分配链的形式呈现。FAT32中的每个簇的簇地址,使用32bit记录在FAT表中。FAT表中的所有字节位置以4个字节为单位进行划分,并对所有的字节以0开始进行编号(0号与1号被系统保留),从2号的地址开始,每个地址对应于数据区的簇号,FAT表中的地址编号与数据区中的簇号相同。
当文件系统被创建时,分配给FAT区域的空间会被清空,在FAT的0和1号表项中写入特定值(0x0FFFFFFF)。文件系统根目录会被创建,并为根目录分配一个簇的空间(2号簇),并在2号簇对应的FAT表项中写入结束标记(FAT表项非0,代表对应的簇已经被分配,如果表项内容为结束标记,说明对应的簇为文件的最后一个簇,如果对应的表项为其他值,则该值为指向文件下一个簇的簇号)。
数据区的开始位置紧接着FAT区,通过计算可以得到,数据区开始于(34+9999*2)*512,数据区的第一个簇的簇号为2(与FAT对应),可通过如下方式从数据簇号计算簇的起始位置:【保留区扇区数 + FAT扇区数 * FAT表数 + (簇号-2)* 每簇扇区数】。
大致的计算:
C盘的扇区数为81931392,则对应C盘的大小为81931392*512 = 40G
数据区的大小(扇区数)为81931392 – 34 – 2 *9999 = 81911360
数据区包含的簇数81911360 / 64 = 1279865
数据区需要的FAT扇区数为 1277865 * 4 / 512 = 9998.9。
以上的计算说明FAT表项数略大于数据簇的数目,那么在分区大小确定时,应该如何确定FAT扇区数呢?要确定FAT扇区数,必须先确定系统保留块数,FAT表的个数,以及簇的大小这三个参数。
以上述的C盘为例,C盘扇区数为81931392,现在系统需要34个保留扇区,需要2个FAT表,簇的大小为32K,可做如下计算确定FAT表的扇区数。
1. 每个FAT的扇区对应于512/4个簇,也即128 * 64个扇区(32k),1:8192;
2. 由于系统需要2个FAT表,故FAT区与数据区关系应为1:4096;
3. 用于FAT表与数据区的扇区数为81931392 – 34 = 81931358;
4. 每个FAT表的扇区数约为81931358 / 4097 / 2 = 9998.945;
5. FAT表的表项只能大于或等于数据区的簇数,故应该向上取整,结果为9999。
FAT32的目录项:
当新的文件或目录被创建时,FAT32会在其父目录的数据区为新的文件增加目录项,并更新父目录的FAT表。文件的目录项中包含文件第一个簇的簇号,文件属性,文件创建时间,最后写入时间,文件名等信息,对于短目录项(支持8+3长度的文件名),对于文件名很长的文件,则需要建立长目录项(长目录项按逆序存放)。以下三个图的统计信息,分别为普通短目录项,长目录项(0x0F标志)以及卷标目录项。长目录项中包含一个校验和字段,如果一个文件包含多个长目录项,则这些长目录项的校验和字段是相同的。另外,与unix文件系统相同,目录的目录项中包含.和..这两个特殊的目录项。
创建文件(目录)的大致过程(如C:\a\b\c.txt,假设a,b目录已存在,创建c.txt文件)
1. 读取根目录的各个目录项(根目录的第一个簇为2),将目录项的文件名与a进行对比,找到a目录的目录项信息。如果在2号簇上没有找到,则查看2号FAT表项的内容(下一个簇的簇号),在根目录的下一个簇上继续查找,依次类推,直到找到a的目录项信息。
2. 根据a的目录项,获取a目录第一个簇的簇号(通过该簇号能获取a目录所有簇链的簇号信息),依次查找a目录中的各个目录项找到b的信息,过程同1。
3. 为c.txt创建目录项(假设原来不存在c.txt文件),并将其加入到b目录中,如果b目录原来分配簇的空间不够,则为b分配新的簇,并更新FAT表,将c.txt的目录项写到新的簇中(普通文件内容的扩充过程与此类似)。