:FAT16/FAT32文件结构1

来源:百度文库 编辑:九乡新闻网 时间:2024/05/05 14:07:20

最近刚好做一个嵌入式系统,需要自己做个文件系统,在享受前辈的丰硕成果的同时,也发现网上流传的文档,有个别关键点解释得不是很详细,特整理一下自己的理解供大家品评,不管是野草味还是牛奶味,网上能搜索到的基本内容就不重复了。

总结,FAT16/FAT32文件结构的几点精细解释!

1、如何判别所读扇区是不是文件系统的起始扇区(即首扇)?

以前愚以为认定第3个字节开始,看是不是MSDOS5.0字符串就可以了,当然这样的识别或许正确率已达99%,但毕竟不是千足纯金,这样的认定的确是“愚以为”,某些格式化工具是够“狗胆”不打上这个标志的,只是打上自己的“陋狗”(logo)。

貌似Windows这边是以第0个字节是不是0xEB为标志,但Winhex至少还要认第2个字节是不是0x90,才能认定这个扇区是不是首扇。

貌似还可以认定第0x1FE是不是0x55,第0x1FF是不是0xAA,至少目前还没有看到其他格式化工具够“狗胆”不打这个标志的,但也不是很确定。

2、如何认定所读的文件系统是FAT16还是FAT32?

在首扇打上MSDOS5.0字符串的盘子里,一般在0x52打上FAT32,或者在0x36打上FAT16。

当然也是,既然MSDOS5.0不可靠,那么FAT16或FAT32这样的字符串也是不可靠的。

在文件的首个扇区,貌似有用的信息包括:

(1)、每个扇区的字节数,在(0xB 0xC)偏移处,貌似是固定的(00 02), 即十进制是512,还不知道有那个格式化工具够“狗胆”不是512?

(2)、每簇的扇区数,在(0xD)偏移处,这个数字有大有小,据说FAT32多数是8,FAT16最大不超过32,但不要信以为真。

(3)、保留扇区数,在(0xE 0xF)偏移处,这个数字表示FAT表开始的扇区,FAT16保留较少,FAT32保留较多,里面可以藏污纳垢大大的了。

(4)、FAT数,在(0x10)偏移处,一般都是2,还不知道有那个格式化工具够“狗胆”不是2?

(5)、一个FAT包括多少个扇区,在(0x16 0x17)偏移处,这个数字仅是代表FAT16,对于FAT32这里固定为0,还不知道有那个格式化工具在格式化FAT32时够“狗胆”不是0?

这就回答了本道问题,通过这个数字是不是0来判别,是0则为FAT32,不是0则是FAT16(特别提示,不理会FAT12或其他格式,不要拿FAT12抬杠)

那么FAT32的数字在那里呢?在(0x24 0x27)偏移处,是个long型,够有型。

(6)、这里还有两个数字比较重要,但是很多文章貌似忽视了它们,在做精细分析时,却不得不提。

隐含的扇区数,在(0x1C 0x1F)处,一般是指在文件系统前,设置了多少个扇区做其他用途,比如在mp3的产品中用于烧录程序。

文件系统的总扇区数,在(0x20 0x23)处,这个数据其实是很重要的,下文即见分晓。

回到第一个问题,要是谁够“狗胆”,可以试试通过0xB 0xC 0x10是不是00 02 02来判断是不是首扇。

3、根目录占据多少扇区?

FAT16固定为32个扇区,FAT32首先是占据一簇,例如8个扇区,以后可以一簇一簇来分配,直到盘满恒久远,一扇一簇永流传。

4、有效的簇有多少?有效的簇号是什么?

在一般分析文件系统时,不太关注这个问题,但是如果要精确到每一簇是不是有效的,则需要计算这个参数。

能够用于u盘数据区的扇区数 = 文件系统的总扇区数 - 保留区 - FAT包含的扇区 * FAT数 - 根目录所占扇区数

有效的簇 = 用于u盘数据区的扇区数 / 每簇扇区数

哈哈,这里需要的参数,在上面都一一抽出来了吧,好数据是不要怕挨抽的。

所以,由于u盘的用于文件系统的扇区数不一定刚好符合一簇的大小,多少剩余几扇(小于一簇)永远是用不上的,漂移在文件系统之外,牛人可以在这里埋伏一点好玩的东东,让菜鸟级的翻版制造商觉得背后痒痒的,但又抓不到痒。

由于0和1不是有效的簇号,所以有效的簇号是:FAT16是从2到(有效的簇数+2),FAT32是从3到(有效的簇数+3)

在格式化FAT32后,通常会发现已经有4096(每簇=8扇)的空间被使用了,这是指已经有一簇用在根目录了。


5、不够严谨的格式化

从第4点知道,格式化后u盘就会有个最大的有效簇号,比它更大的簇号就没有相应的空间与之对应了,但是FAT所能容纳的簇号是128(FAT32)或256(FAT16)的整数倍,所以,在FAT的最后一扇,会有比最大的有效簇号更大的簇号存在,严谨地,这些簇号应该打上坏块(0xFFF7或0x0FFFFFF7),但是貌似格式化工具在格式化时虽然够“狗胆”却没有这么做,一般都是0,变成疑似的可用空间,被某些笨笨的嵌入系统中的某个笨笨的函数使用,误判还有很多剩余空间。

6、什么时候要用长文件名?

(1)、文件名大于8个字符,后缀名大于3个字符,这个容易理解;
(2)、文件名或后缀名大小字母混合时也要用长文件名,反之如果文件名或后缀名是青一色的大写或小写,则不用长文件名。

在文件目录项的32个字节中,在(0xC)偏移处,如果它的值为0x00,表示文件名是大写,后缀名也是大写,简称“大大”,如果它的值是0x10,表示“小大”,0x18表示“小小”,0x08表示“大小”。

7、关于长文件名的校验码

网上有一段非典型的计算长文件名校验码的代码被广泛传播,作者可谓用心良苦,算法解释得很清楚,但是又不希望使用者只是Ctrl+C、Ctrl+V,要经过自己的大脑整理一下,所以是做过技术处理的。

被广泛传播的代码是这样的:

 int i,j,chknum=0;
 for (i=11; i>0; i--)
chksum = ((chksum & 1) ? 0x80 : 0) + (chksum >> 1) + shortname[j++];

感觉改成这样就可以了:

 int i;
 unsigned char chknum=0;
 for (i=0; i<11; i++)
  chksum = ((chksum & 1) ? 0x80 : 0) + (chksum >> 1) + shortname[i];