本人写文章,难免有错误的地方请大家谅解,如果有错误请大家指教,现在开始正题,大家都知道FAT文件系统不是什么新鲜的文件系统了,目前用此文件系统的设备很多,比如现在的数码相机、数码摄像机、手机等等设备都以FAT作为它管理文件的一个系统,因为FAT文件系统的结构相对简单,容易理解,FAT文件系统进行了数次的升级,从FAT12进化到FAT16直到FAT的最后版本FAT32(还有一个是exFAT因为和FAT还是略有不同,在此就不多做介绍),今天就以FAT最新的FAT32文件系统作为本将的开始,网上类似讲解FAT文件系统的文章也很多,我就讲解最重要的一些知识,也是我的一些经验,希望能对各位爱好数据恢复的朋友们有所帮助。
 
了解一个文件系统就要从最基础的开始,我们先从 FAT32 DBR DOS BOOT RECORD DOS 引导记录)讲起, DBR 分为两部分: DOS 引导程序和 BPB BIOS 参数块)。其中 DOS 引导程序完成 DOS 系统文件( IO.SYS MSDOS.SYS )的定位与装载,而 BPB 用来描述本 DOS 分区的磁盘信息,如比较重要的参数有“每个扇区的字节数”、“每个簇有多少个扇区”、“保留扇区”、“ FAT 表数量”、“扇区总数”、“每 FAT 扇区数”,现在就从上述列出的几个关键的参数做详细的讲述:
 
1 、每个扇区的字节数:
 
就是一个扇区共有多少个字节来组成,一般情况都是 512 个字节为一个扇区, 16 进制表示为 200H
 
2 、每个簇有多少个扇区:
 
就是一个簇包含了多少个扇区,他的表示都是 2 的次方( 512 字节 1 2 4 8 16 32 64 扇区),比如 8 个扇区构成一个簇,它的簇大小就是 8 16 进制表示为 8H
 
3 、保留扇区:
 
就是 DBR FAT 表之间共有多少个扇区。
 
4 FAT 表数量:
 
表示该分区上的 FAT 表共有几个副本,一般情况都为 2 (注:在重建 DBR 的情况下可以灵活调配)。
 
5 、扇区总数:
 
表示该分区的扇区数量。
 
6 、每 FAT 扇区数:
就是单个 FAT 表的扇区总数,通过次参数配合上面的参数就能够定位到根目录也就是 Root ,公式为:保留扇区 +FAT 表数量 * FAT 扇区数 = 根目录的地址。
 
上述就是最为重要的几个 BPB 参数的解释,下面是 DBR 的截图,让大家看一下:
 
 
剖析FAT文件系统结构_第1张图片
 
WinHEX 扇区截图
 
剖析FAT文件系统结构_第2张图片
 
WinHex 模板解释出来的 BPB 参数
 
    在此提供一个WinHex调用的模板,大家可以把----------------------之间的代码复制到一个记事本中,保存为以TPL为扩展名的文件,然后存放到WinHex的目录中即可。
 
 
--------------------------------------------------------------------------
template "FAT32 引导扇区 "
 
// Template by Stefan Fleischmann
// X-Ways Software Technology AG
 
// 适用于 FAT32 格式逻辑驱动器的 0 扇区。
 
description "BIOS 参数块 (BPB) 和其它 "
applies_to disk
sector-aligned
 
requires 0x02  "90"
requires 0x52  "46 41 54 33 32" // ="FAT32" 在偏移地址 52
requires 0x1FE "55 AA"
 
begin
       read-only hex 3 "JMP 指令 "
       char[8]    "OEM"
 
       section    "BIOS 参数块 "
       uint16     " 字节 / 扇区 "
       uint8              " 扇区 / "
       uint16     " 保留扇区 "
       uint8              "FAT 计数 "
       uint16     " 根项目 ( 未使用 )"
       uint16     " 扇区 ( 小容量 )"
       hex 1             " 媒介描述 (16 进制 )"
       uint16     " 扇区 / FAT ( 小容量 )"
       uint16     " 扇区 / 磁轨 "
       uint16     " "
       uint32     " 隐藏扇区 "
       uint32     " 扇区 ( 大容量 )"
      
       section    "FAT32 扇区 "
       uint32     " 扇区 / FAT"
       uint16     " 延迟 "
       uint16     " 版本 "
       uint32     " 根目录第 1 "
       uint16     "FSInfo 扇区 "
       uint16     " 备份引导扇区 "
       read-only hex 12 "( 保留 )"
       endsection
      
       hex 1             "BIOS 驱动 (16 进制 , HD=8x)"
       read-only uint8 ( 未使用 )
       hex 1             " 扩展启动特征 (29h)"
       uint32     " 卷序列号 (10 进制 )"
       move -4
       hex 4             " 卷序列号 (16 进制 )"
       char[11] " 卷标签 "
       char[8]    " 文件系统 "
       endsection
 
       goto        0x1FE
       read-only hex 2 " 特征 (55 AA)"
end
 
--------------------------------------------------------------------------
 
至此上述所说的就是 BPB 参数极为重要的参数,下面讲述一下 FAT 表的作用。
 
了解 FAT 表之前我们先了解一下如何定位到 FAT 表,我们如何才能知道 FAT 的具体位置呢,上面已经讲到 FAT 表的位置就在“保留扇区”中记录,他里面记录了 FAT1 表的位置;为什么要有 FAT 表呢,有两大用途,我分别做阐述:
 
用途一:
 
我们在使用文件系统的过程中,会有“建立”、“删除”、“移动”等动作,就会造成文件系统中有大量的不连续的簇的产生,如果存储文件的时候文件系统只把文件存储到连续的簇中就会造成非常之严重的空间浪费,所以 FAT 表的产生的原因之一简单的说就是把那些不连续的簇在存储文件的时候通过 FAT 表项的指针做指引来把不同地方的空间给它“集合”起来,在读取文件的时候通过这个链表( FAT 表的指向)就很轻松的把文件读取出来了。
 
通途二:
 
如果对 NTFS 有一定了解的网友们就会知道, NTFS 里面有一个元文件名为“ $Bitmap ”他就是记录整个文件系统的空间使用情况的,在 FAT 文件系统中 FAT 表也就充当了空间利用率的作用。
 
在来说一下 FAT 表内的特征, FAT32 文件系统中的 FAT 表是 4 个字节描述一个簇,也就是一个 32 位的指针。他的特征一般为:“ F8 FF FF 0F FF FF FF FF ”第一个字节 F8 是同 BPB 参数中的“媒介描述符”而定,他们是一样的,在修复文件系统的时候上面的特征作为辅助判断,请文友朋友们自由发挥。
 
下面讲述一下 FAT32 文件系统中的根目录,相比 FAT32 文件系统之前的版本的 FAT 文件系统来说 FAT32 文件系统在根目录的设计上的确优于它的前身 (FAT12 & FAT16) ,不知道大家注意到没有,在使用 FAT32 之前的 FAT 的版本文件系统的时候会遇到这样的问题,就是在根目录存储过多的文件的时候提示“无法创建文件夹”等消息提示,如图:
 
剖析FAT文件系统结构_第3张图片
 
此时我们看磁盘属性的剩余空间还是有很多的,如图:
 
剖析FAT文件系统结构_第4张图片
 
可用空间还有 247MB ,为什么存不下了呢,答案因为 FAT32 之前的版本的根目录没有在数据区中,而是在格式化的时候就跟定死了,所以导致有剩余空间但是在根目录建立过多的文件或者文件夹的时候报错,如果以 8.3 标准命名的文件夹或者文件在存储到根目录的时候可以存放共有 512 个目录项,如果在格式化的时候输入了分区的卷标,那就存放不了 512 个目录项了,可存放的目录项就是 511 个,如果在已经存有 512 个目录项的文件系统上想添加分区的卷标就不行了,因为卷标也是占用目录项的位置的,还有一种可能就是在根目录如果超过 8.3 命名规则,那么存放在根目录的目录项就更少了,因为有长名的存在,而 FAT32 是把根目录移植到了数据区中,就好比管理一个文件一样去管理根目录,这样就解决了根目录不能存放太多文件的限制了,因为通过 FAT 表的指向,开辟一个新的空间存放其余的根目录项。
 
剖析FAT文件系统结构_第5张图片
 
目录项模板截图
 
在此提供一个 WinHex 调用的模板,大家可以把 ---------------------- 之间的代码复制到一个记事本中,保存为以 TPL 为扩展名的文件,然后存放到 WinHex 的目录中即可。
 
--------------------------------------------------------------------------
template "FAT Directory Entry"
 
// Template by Stefan Fleischmann
// X-Ways Software Technology AG
 
// To be applied to a sector of a FAT16 or FAT32 drive
// that contains a directory. Not suitable for LFN
// (long filename) directory entries.
 
description "Normal/short entry format"
applies_to disk
multiple
 
begin
       char[8]    "Filename (blank-padded)"
       char[3]    "Extension (blank-padded)"
       hex 1             " 0F = LFN entry"
       move             -1
       binary     "Attributes ( - -a-dir-vol-s-h-r)"
       goto        0
       hex 1             "00 = Never used, E5 = Erased"
       move             11
       read-only byte "(reserved)"
       move             1
       DOSDateTime       "Creation date & time"
       move             -5
       byte        "Cr. time refinement in 10-ms units"
       move             2
       DOSDateTime       "Access date (no time!)"
       move             2
       DOSDateTime       "Update date & time"
       move             -6
       uint16     "(FAT 32) High word of cluster #"
       move             4
       uint16     "16-bit cluster #"
       uint32     "File size (zero for a directory)"
end
--------------------------------------------------------------------------
 
至此大概的 FAT32 文件系统结构就先告一段落,说明一下,如果想了解 DBR FAT 表项、目录项的其它字节的含义请参照相关数据恢复的书籍,因为之前我已经说过我就是把我的一些经验讲出来,如果不明白大家可以一起探讨,最后我再说一下如何创建 FAT32 文件系统的结构(就是格式化 Format ),在此我就提供一个非常重要的一个公式,是我自己着么出来的如何计算单个 FAT 表大小的一个公式,在做格式化 FAT32 文件系统的软件的时候很有用公式如下:
 
单个FAT 表大小= (((分区大小÷每扇区字节数-保留扇区)÷簇大小-2 )×4 ÷每扇区字节数)-((分区大小÷每扇区字节数)% 簇大小)
 
建立完毕结构以后,剩余的使用与管理工作就交给管理文件系统的操作系统来完成了,至此我的讲解到此结束,最后发布一个我做的格式化脚本的录像。
 
联系电话:+0086-158-4651-2151
QQ:104505021 (Windows Hao)
我的博客:http://haobinnan.blog.51cto.com/
联系人:郝槟楠