一、简介FAT FAT及file allocate table,文件分配表,是文件在存储设备上的一种组织形式。 有什么FAT12 、FAT16、FAT32,所谓12 , 16 , 32 指的是表示簇的地址的大小, 好吧,这里可能遇到个问题,啥叫簇,我解释下,一块存储设备,分为n簇,每簇里 有包含有n分区及sector,每块分区大小固定死了。 二、 介绍两个名词 MBR 和 DBR MBR-------主引导记录
1.创建时间:由分区软件(Fdisk/PartitionMagic/Windows 2000/Windows XP安装工具等)给硬盘分区时建立的。
2.功能 :存放硬盘分区信息和引导系统时检查分区。
3.作用范围:MBR和虚拟MBR控制着整个硬盘的所有分区信息,可定义1~4个不等的分区,作用范围是全局性的。
4.所占硬盘空间大小:占1个扇区 512字节
5.位于 :硬盘的0柱面,0磁道,1扇区
6.组成结构:偏移:0~138 引导程序(139字节),检测所有分区。
139~217提示信息区(79字节),存放报错信息。
218~445保留区(228字节),未用。
446~509区信息表(64字节),可存放4个分区的基本信息。
510~511结束标志 55AA
7.标志 :55AA
小提示:MBR共32*16=512个字节,前面446个字节是与操作系统有关的
后面446~509(64字节)是分区信息表,可存放4个分区的基本信息
0扇区可能有MBR扇区也可能没有
DBR--------操作系统引导记录扇区
1.创建时间:由高级格式化软件(Format等)格式化分区时创建。
2.功能:引导系统和保存文件系统参数。
3.作用范围:局部性的,1个DBR只能定义1个分区的系统文件。
4.性质:属于应用性的。
5.所占硬盘空间大小:占1个扇区 512个字节
6.位于:硬盘个分区的开始处
7.组成结构:由5个部分组成:跳转指令(跳转指令JMP+跳转偏移量)
DOS版本号(该部分由8个字节,且随不同DOS版本而有所变化)
BIOS参数块(也称BPB,记录着分区重要的参数信息)
DOS引导程序(该部分是Boot代码)
结束标志 55AA
小提示:给硬盘分区产生MBR→格式化硬盘分区产生DBR,所以先有MBR,然后才有DBR。 三、FAT32组织结构 FAT32由DBR, FDT,和数据区
1,、 DBR详细分析
偏移00H: 3字节的 跳转指令 EB 58 90,跳过下面的BPB和扩展BPB部分 偏移03H:8字节的硬盘分区类型文本字符名:4D 53 44 4F 53 35 2E 30 即: MSDOS5.0 偏移0BH: 25字节的分区参数块(BPB),细分如下: 偏移0BH:扇区字节数 00 02 即0X0200,512字节 偏移0DH:每簇扇区数 08即每簇包括8个扇区 偏移0EH:保留扇区数 24 00即保留36个扇区 偏移10H:FAT表份数 02即两个FAT表
偏移11H:未用 00 00
偏移13H:未用 00 00 偏移15H:介质类型 F8即本地硬盘 偏移16H:未用 00 00 偏移18H:每磁道扇区数 3F 00 即每磁道63扇区
偏移1AH:磁头数 FF 00即255个磁头 偏移1CH:隐藏扇区数 80 1F即8064个隐藏扇区
偏移20H:磁盘总扇区数 80 F0 77 00即总共7860352个扇区(7860352*512=4024500224,因为我的U盘是4G) 偏移24H:52字节的扩展分区参数块(扩展BPB),细分如下: 偏移24H:FAT表占用扇区数 EE 1D 00 00即FAT表占7662个扇区 偏移28H:未用 00 00 00 00 偏移2CH:根目录入口簇号 02 00 00 00即根目录从02号簇开始
偏移30H:文件系统信息扇区号 01 00即扇区1 偏移32H:备份引导扇区的位置 06 00即6号扇区(第7个扇区),从WINHEX中我们也可以看到,6号扇区的内容和0号引导扇区内容 是 一样的 偏移34H:未用 00 00 00 00 00 00 00 00 00 00 00 00 偏移40H:物理磁盘号 00 偏移41H:未用 00 偏移42H:扩展引导标志 29即0X29 偏移43H:磁盘序列号F1 2A 27 04通常为一随机数
偏移47H:卷标ASCII 4E 4F 20 4E 41 4D 45 20 20 20 20 即NO NAME 偏移52H:文件系统格式ASCII 46 41 54 33 32 20 20 20即FAT32 偏移5AH:分区引导代码 420字节: 33C98ED1BCF47B8EC18ED9BD007C884E028A5640B408CD137305B9FFFF8AF166 0FB6C640660FB6D180E23FF7E286CDC0ED0641660FB7C966F7E1668946F8837E1 6007538837E2A007732668B461C6683C00CBB0080B90100E82B00E94803A0FA7DB 47D8BF0AC84C074173CFF7409B40EBB0700CD10EBEEA0FB7DEBE5A0F97DEBE0 98CD16CD196660663B46F80F824A00666A0066500653666810000100807E02000F8 52000B441BBAA558A5640CD130F821C0081FB55AA0F851400F6C1010F840D00FE4 602B4428A56408BF4CD13B0F96658665866586658EB2A6633D2660FB74E1866F7F1 FEC28ACA668BD066C1EA10F7761A86D68A56408AE8C0E4060ACCB80102CD13666 10F8254FF81C300026640490F8571FFC34E544C445220202020202000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000 00000000000000D0A52656D6F7665206469736B73206F72206F74686572206D656469 612EFF0D0A4469736B206572726F72FF0D0A507265737320616E79206B657920746F2 0726573746172740D0A0000000000ACCBD80000 偏移1FEH:有效扇区结束标志 55 AA 到此分区引导扇区介绍结束。 2、FDT详细介绍 FAT表项由FAT1和FAT2组成。 FAT1表位置的定位: 在我们前面介绍分区引导记录的时候提到,在偏移0EH处存储了保留扇区的个数,这个保留扇区数指的就是当前分区内DBR到FAT表之间的所有扇区的个数(包括DBR但不包括FAT表)。 FAT2表位置的定位: 在我们前面介绍分区引导记录的时候提到,在偏移24H处存储了FAT表所占用的扇区个数,我们又知道FAT2是紧邻FAT1的,所以可以很容易得到FAT2的存储位置的偏移地址。
FAT表的特性: FAT表由一系列大小相等的FAT表项组成,它有如下特性: FAT表项由0和1号簇组成,FAT表项的成员都是以4字节为对齐单位,其中FAT表项中0和1号地址被系统保留以存储特殊标记内容,从2号开始(对应数据区的簇号)存储数据区每簇的信息,这些信息分为四个
1,、如果某个簇未被分配使用,它所对应的FAT表项内的FAT表项值即用0进行填充,表示该FAT表项所对应的簇未分配使用。
2、当某个簇已被分配使用时,则它对应的FAT表项值也就是该文件的下一个存储位置的簇号。 3、如果该文件结束于该簇,则在它的FAT表项中记录的是一个文件结束标记EOF,对于FAT32而言,代表文件结束的FAT表项值为0x0FFFFFFF。
4、如果某个簇存在坏扇区,则整个簇会用FAT表项值0x0FFFFFF7标记为坏簇,不再使用,这个坏簇标记就记录在它所对应的FAT表项中。 三、数据区 这里我把根目录区也放在这里了。 当文件系统被创建,也就是进行格式化操作时,分配给FAT区域的空间将会被清空,在FAT1与FAT2的0号表项与1号表项写入特定值。由于创建文件系统的同时也会创建根目录,也就是为根目录分配了一个簇空间,通常为2号簇,所以2号簇所对应的2号FAT表项也会被写入一个结束标记。 每个目录对应一个簇号,每个簇里存储的可以是文件目录,也可以是目录目录。 目录目录里的簇地址就是目录地址,或者文件地址,有点绕吧,呵呵,
其实数据区真没什么好说的,到此为止差不多了,接下来就是分析FAT32源码了,其实难也不难,关键在于恒心,将到此大概知道我意思了吧,源码还是自己去分析,呵呵!不多说了,看源码去了! 再补充一点关于文件和目录的存储 struct direntry
{
UINT8 deName[8]; // 文件名,不足部分以空格补充
UINT8 deExtension[3]; // 扩展名,不足部分以空格补充
UINT8 deAttributes; // 文件属性
UINT8 deLowerCase; // 0
UINT8 deCHundredth; // 世纪
UINT8 deCTime[2]; // 创建时间
UINT8 deCDate[2]; // 创建日期
UINT8 deADate[2]; // 访问日期
UINT8 deHighClust[2]; // 开始簇的高字
UINT8 deMTime[2]; // 最近的修改时间
UINT8 deMDate[2]; // 最近的修改日期
UINT8 deLowCluster[2]; // 开始簇的低字
UINT8 deFileSize[4]; // 文件大小
}; 簇里存放文件的数据或者文件,或者目录。OK
四、源码分析完毕,不要小看源码少,还是有点小难度的!
|