1.引言
FAT文件系统在Windows比较常见,相对于ext系统而言,也比较简单。是学习文件系统的切入点。
2.FAT16的基本结构
首先先了解下FAT16文件系统的基本结构依次为:DBR扇区、FAT表1、FAT表2、根目录和数据区。
DBR扇区:DBR是操作系统可以直接访问的第一个扇区,包括一个引导程序和一个称为BPB的本分区参数记录表。引导程序的主要任务是当MBR将系统控制权交给它时,判断本分区跟目录前两个文件是不是操作系统的引导文件。如果确定是,就将其读入内存,并把控制权交给该文件。BPB参数块记录着本分区的启始扇区、结束扇区、文件存储格式、硬盘介质描述符、根目录大小、FAT个数、分配单元的大小等重要参数。
FAT1,FAT2:是簇的链表。在根据目录项获取文件的首簇号后,在FAT 找到对应的簇,可以找到下一个簇,一直到文件结束。对于FAT16,每个簇用16Bit来表示,而对于FAT32,使用32Bit来表示。这应该是两者之间的重要区别。
根目录:根目录的作用就是有文件或者目录的首簇号,以及文件的长度(目录的长度是0)。FAT16中,根目录的所占空间可以根据BPB中的参数——Maximum Root Directory Entries(0x11,2bytes)。
数据区:文件等数据待的地方。紧跟着根目录。从2号簇开始。
3.查找文件的过程
根据DBR中的一些参数得到FAT和根目录的位置。根据根目录得到次级目录的簇号(对于更多级的目录依此类推),来到该簇后,再根据文件名得到查到对应的文件的首簇和文件长度。根据文件长度得到文件所占的簇的数量。由首簇号到FAT查看文件的簇链表,依次得到文件的各个簇,从而也就得到了文件的全部内容。
4.查找文件示例
选取安卓手机中modem 分区作为对象。modem 在机台里的挂载点是firmware,可以adb shell 进去系统之后,cd firmware看看里面的内容。里面有两个文件夹:image和verinfo。而我的目的就是要读到verinfo文件夹里面的文件ver_info.txt。将modem dd出来,然后使用winhex查看二进制文件。
4.1 DBR
先看通过winhex查看的结果。这个扇区里面基本上能得到大部分的文件系统的参数。(特别注意,存储是按照小端模式)
下面的表,解释了一些主要参数的意义。
4.2 FAT
根据上面的参数,我们可以算出FAT1的偏移地址以及根目录的偏移值。
FAT1偏移地址:保留扇区(FAT1之前的扇区,包括引导扇区)之后就是FAT1。因此可以得到,FAT1的偏移地址就是1个扇区的位置,也就是512。
FAT2偏移地址:FA1偏移地址+FAT1的大小,512+21*512 = 11264
2字节表示一个簇的状态。具体意义如下表所示:
每个簇对应的0x0002-0xFFEF之间的值,表示要读取文件那么下一个簇的簇号。
4.3 根目录
根目录偏移地址: FAT2偏移地址+ FAT2的大小,11264+21*512= 22016
下面看一下根目录的前面部分:
看到这里,就可以看到前面提到的两个文件夹了。在根目录中,一个文件或者一个目录用32字节来表示。
因此,可以得到,verinfo目录的首簇号是 9F 12 也就是 0x129F = 4767号簇。
根目录的偏移地址是22016,根目录占32个扇区,所以,2号簇的位置是:22016+32*512=38400 。可以得到verinfo的偏移地址是38400 +(4767-2)*512*32 = 78108160
看看这个位置的二进制:
显然,接下来可以看到这个目录下面,会有ver_info.txt的文件的首簇号和文件的长度。首簇号是 A0 12 也就是0x12A0=4768。文件长度是1F 也就是31<<512*32,因此只占一个簇,不需要回去查看FAT来找到剩下的簇。
根据簇号,又可以得到这个文件所在位置:(4768-2)*512*32+38400 = 78124544
看看这个位置的二进制:
到这里,也就看到了我们要查看的文件的内容。事实上,这和用mount挂载出来看到的结果是一样的,撒花~~
看这个还是花了很多时间的。FAT16和FAT32也有所区别,但是实际上大同小异。下篇写ext2文件系统的结构。
参考文章:http://www.xuebuyuan.com/598485.html
http://blog.csdn.net/menghnhhuan/article/details/4270168
非常感谢!