FAT文件系统引导扇区学习总结

  • Post author:
  • Post category:其他


分区引导扇区()DBR,通常被称为0扇区(0thsector)。其实称它为0扇区其实是不准确的,这样容易让人误解它为磁盘的最前面一个扇区,称它为0扇区只是表明它是FAT中扇区的参考点而已。

该扇区中包含有我们关注的一个重要数据结构BPB(BIOS Parameter Block)。

标识 偏移(字节) 长度(字节) 说明
BS_jmpBoot 0x00 3 跳转指令,指向启动代码
BS_OEMName 0x03 8 建议值为“MSWIN4.1”。有些厂商的FAT驱动可能会检测此项,所以设为“MSWIN4.1”可以尽量避免兼容性的问题
BPB_BytsPerSec 0x0B 2 每扇区的字节数,取值只能是以下几种:512,1024,2048或是4096。设为512会取得最好的兼容性,目前有很多FAT代码都是硬性规定每扇区的字节数为512,而不是实际的检测此值。但微软的操作系统能够很好支持1024,2048或是4096
BPB_SecPerClus 0x0D 1 每簇的扇区数,其值必须中2的整数次方(该整数必须>=0),同时还要保证每簇的字节数不能超过32K,也就是1024*32字节
BPB_RsvdSecCnt 0x0E 2 保留扇区的数目,此域不能为0,FAT12/FAT16必须为1,FAT32的典型值取为32,微软的系统支持任何非0值
BPB_NumFATs 0x10 1 分区中FAT表的份数,,任何FAT格式都建议为2
BPB_RootEntCnt 0x11 2 对于FAT12和FAT16此域包含根目录中目录的个数(每项长度为32字节),对于FAT32,此项必须为0。对于FAT12和FAT16,此数乘以32必为BPB_BytesPerSec的偶数倍,为了达到更好的兼容性,FAT12和FAT16都应该取值为512
BPB_ToSec16 0x13 2 早期版本中16bit的总扇区,这里总扇区数包括FAT卷上四个基本分区的全部扇区,此域可以为0,若此域为0,那么BPB_ToSec32必须为0,对于FAT32,此域必为0。对于FAT12/FAT16,此域填写总扇区数,如果该值小于0x10000的话,BPB_ToSec32必须为0
BPB_Media 0x15 1 对于“固定”(不可移动)存储介质而言,0xF8是标准值,对于可移动存储介质,经常使用的数值是0xF0,此域合法的取值可以取0xF0,0xF8,0xF9,0xFA,0xFC,0xFD,0xFE,0xFF。另外要提醒的是,无论此域写入什么数值,同时也必须在FAT[0]的低字节写入相同的值,这是因为早期的MSDOS 1.x使用该字节来判定是何种存储介质
BPB_FATSz16 0x16 2 FAT12/FAT16一个FAT表所占的扇区数,对于FAT32来说此域必须为0,在BPB_FATZ32中有指定FAT表的大小
BPB_SecPerTrk 0x18 2 每磁道的扇区数,用于BIOS中断0x13,此域只对于有“特殊形状”(由磁头和柱面每分割为若干磁道)的存储介质有效,同时必须可以调用BIOS的0x13中断得到此数值
BPB_NumHeads 0x1A 2 磁头数,用于BIOS的0x13中断,类似于上面的BPB_ SecPerTrk,只对特殊的介质才有效,此域包含一个至少为1的数值,比如1,4M的软盘此域为2
BPB_HidSec 0x1C 4 在此FAT分区之前所隐藏的扇区数,必须使得调用BIOS的0x13中断可以得到此数值,对于那些没有分区的存储介质,此域必须为0,具体使用什么值由操作系统决定
BPB_ToSec32 0x20 4 该卷总扇区数(32bit),这里的扇区总数包括FAT卷四个个基本分的全部扇区,此域可以为0,若此域为0,BPB_ToSec16必须为非0,对FAT32,此域必须是非0。对于FAT12/FAT16如果总扇区数大于或等于0x10000的话,此域就是扇区总数,同时BPB_ToSec16的值为0
BS_drvNum 0x24 1 用于BIOS中断0x13得到磁盘驱动器参数,(0x00为软盘,0x80为硬盘)。此域实际上由操作系统决定
BS_Reseved1 0x25 1 保留(供NT使用),格式化FAT卷时必须设为0
BS_VolID 0x26 1 扩展引导标记(0x29)用于指明此后的3个域可用
BS_BootSig 0x27 4 卷标序列号,此域以BS_VolLab一起可以用来检测磁盘是否正确,FAT文件系统可以用此判断连接的可移动磁盘是否正确,引域往往是由时间和日期组成的一个32位的值
BS_VolLab 0x2B 11 磁盘卷标,此域必须与根目录中11字节长的卷标一致。FAT文件系统必须保证在根目录的卷标文件列改或是创建的同时,此域的内容能得到时的更新,当FAT卷没有卷标时,此域的内容为“NO NAME”
BS_FilSysType 0x36 8 以下的几种之一:“FAT12”,“FAT16”,“FAT32”。不少人错误的认为FAT文件系统的类型由此域来确认,仔细点你就能发现此域并不是BPB的一部分,只是一个字符串而已,微软的操作系统并不使用此域来确定FAT文件的类型;因为它常常被写错或是根本就不存在。

FAT32的BPB的内容和FAT12/16的内容在地址0x24以前是完全一样的,从偏移量0x24开始,他们的内容有所区别。下面举个例子来分析上面介绍的内容。

FAT16文件系统

看0x00处的3个字节指向0x903CEB(此系统为小端模式),说明启动代码在0x903CEB处。再看0x03处的8个字节为”4D 53 44 4F 53 35 2E 30”对应的字符为“MSDOS5.0”。下面是每扇区字节数(BPB_BytsPerSec),0x0B处的2个字节为0x0200即512个字节。每簇的扇区数(BPB_SecPerClus)0x0D处为0x10即16*512=8K大小。保留扇区的数(BPB_RsvdSecCnt)0x0E处的2个字节为0x0004即保留4个扇区。

分区中FAT表的份数(BPB_NumFATs)0x10处为0x02即2份。对于FAT12和FAT16此域为包含根目录中目录的个数(BPB_RootEntCnt)0x11处的2个字节为0x0200即512个。

总扇区数(BPB_ToSec16)0x13处的2个字节为0x0000,由于后面可见其总扇区数大于0x10000,所以该值为0,总扇区数由BPB_ToSec32决定。

BPB_Media的值对于非可移动存储介质0x15处为0xF8。FAT12/FAT16一个FAT表所占的扇区数(BPB_FATSz16)0x16处的2个字节为0x00F2即242个扇区。每磁道的扇区数(BPB_SecPerTrk)0x18处的2个字节为0x003F即63个扇区。磁头数(BPB_NumHeads)0x1A处的2个字节为0x00FF即255个。在此FAT分区之前所隐藏的扇区数(BPB_HidSec)0x1C处的4个字节为0x0000 003F即63个扇区。

该卷总扇区数(BPB_ToSec32)0x20处的4个字节为0x000F 1EC1即990913个扇区。磁盘驱动器参数(BS_drvNum)0x24处为0x00。0x25处为保留域0x00。扩展引导标记(BS_VolID) 0x26处为0x29表示此后的3个域可用(0x27-0x29)。卷标序列号(BS_BootSig)0x27处的4个字节为0x9C93 850F,由于前面限定到0x29可用,所以卷标序列号为0x93850F。磁盘卷标(BS_VolLab)0x2B处的11个字节为”4E 4F 20 4E 41 4D 45 20 20 20 20”对应的字符为“N0 NAME ”。

文件系统类型(BS_FilSysType)0x36处的8个字节为”46 41 54 31 36 20 20 20”对应的字符为“FAT16 ”。FAT的类型(FAT12/16/32)只能通过FAT卷中的簇(Cluster)数来判定,Cluster总数的计算:

RootDirSectors = (BPB_RootEntCnt*32) /BPB_BytsPerSec 
DataSect = TotalSec 
– (BPB_RsvdSecCnt +(BPB_NumFATs * FATSz) + RootDirSectors) 
CountofClusters = DataSec / BPB_SecPerClus 
If (CountofClusters < 4085) { 
/*卷类型是 FAT12 */ 
} else if(CountofClusters < 65525) { 
/* 卷类型是FAT16 */ 
} else { 
/* 卷类型是 FAT32 */ 
} 

按照上面的值我们来计算一下根目录占据的Sector数:

RootDirSectors = (512*32) / 512 = 32
DataSect = BPB_ToSec32 – (4 + (2 * BPB_FATSz16) + 32)
       = 990913 – (36 + (2 * 242)) = 990393
CountofClusters = 990393 / 16 = 61899

算出的CountofClusters小于65525,说明其是FAT16文件系统。

下表为FAT32的引导扇区内容,只看0x24开始不一样的地方即可

标识 偏移(字节) 长度(字节) 说明
BPB_FATSz32 0x24 4 一个FAT表所占的扇区数,此域为FAT32特有,同时BPB_FATSz16必须为0
BPB_Flags 0x28 2 此域FAT32特有。Bits0-3:不小于0的FAT(active FAT)数目,只有在镜像(mirrorig)禁止时才有效。Bits 4-6: 保留   Bits 7: 0表示FAT实时镜像到所有的FAT表中 1 表示只有一个活动的FAT表。这个表就是Bits0-3所指定的那个    Bits8-15: 保留
BPB_FSVer 0x2A 2 此域为FAT32特有, 高位为FAT32的主版本号,低位为次版本号,这个版本号是为了以后更高级的FAT版本考虑,假设当前的操作系统只能支持的FAT32版本号为0.0。那么该操作系统检测到此域不为0时,它便会忽略FAT卷,因为它的版本号比系统能支持的版式本要高
BPB_RootClus 0x2C 4 根目录所在第一个簇的簇号,通常该数值为2,但不是必须为2。  磁盘工具在改变根目录位置时,必须想办法让磁盘上第一个非坏簇作为根目录的第一个簇(比如第2簇,除非它已经被标记为坏簇),这样的话,如果此域正好为0的话磁盘检测工具也能轻松的找到根目录所在簇的位置
BPB_FSIfo 0x30 2 保留区中FAT32卷FSINFO结构所占的扇区数,通常为1。 在Backup Boot 中会有一个FSINFO的备份,但该备份只是更新其中的指针,也就是说无论是主引导记录还是备份引导记录都是指向同一个FSINFO结构
BPB_BkBootSec 0x32 2 如果不为0,表示在保留区中引导记录的备数据所占的扇区数,通常为6。同时不建议使用6以外的其他数值
BPB_Reserved 0x34 12 用于以后FAT扩展使用,对FAT32。此域用0填充
BS_DrvNum 0x40 1 与FAT12/16的定义相同,只不过两者位于启动扇区不同的位置而已
BS_Reserved1 0x41 1 与FAT12/16的定义相同,只不过两者位于启动扇区不同的位置而已
BS_BootSig 0x42 1 与FAT12/16的定义相同
BS_VolID 0x43 4 与FAT12/16的定义相同
BS_VolLab 0x47 11 与FAT12/16的定义相同
BS_FilSysType 0x52 8 通常设置为“FAT32”,请参照FAT12/16此部分的陈述



版权声明:本文为xinxin_2011原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。