骷髅耳机skullcandy:FAT文件系统原理--规范(1)

来源:百度文库 编辑:九乡新闻网 时间:2024/05/02 11:28:29

FAT文件系统原理--规范(1)  


 

FAT文件起源于70年代末80年代初,用于微软的MS-DOS操作系统。它开始被设计成一个简单的文件系统用于小于500K的软件盘。后来被功能被大大增强用于支持越来越大的媒质。现在的文件系统有FAT12FAT16FAT32三种子类。

FAT12是最早的一版,主要用于软盘,它对簇的编址采用12bit宽度的数,所以称为FAT1212bit的地址可以寻址4096个簇,事实上在FAT12中只能寻址4078个簇(在Linux下可寻址4084个簇),有一些簇号是不能用的,在后面会给出具体的说明。磁盘的扇区是用16bit的数进行计算的,所以磁盘的容量就被局限在32M空间之内。

FAT16中,采用了16bit宽的簇地址,32bit宽扇区地址。虽然32bit的扇区地址可以寻址2^32*512,约2TB的容量, 但于由规定每簇最大的容量不超过1024*32,所以FAT16文件系统的容量也就限制到了2^16*1024*32,大约2.1GB的空量,并且实际还达不到这个值。

FAT32文件系统使用了32bit宽的簇地址,所以称为FAT32。但在微软件的文件系统中只使用了低28位,最大容量为2^28*1024*32,8.7TB的空量。有的人认为32bit全用,最大容量为2^32*1024*32,这种说法是不正确的。

虽然FAT32具有容纳近乎8.7TB的容量,但实际应用中通常不使用超过32GBFAT32分区。WIN2000及之上的OS已经不直接支持对超过32GB的分区格式化成FAT32,但WIN98依然可以格式化大到127GBFAT32分区,但不推荐这样做。

下面是一个FAT分区的构成概况

引导扇区

其他保留扇区(可选)

FAT1

FAT2

根目录区

(仅FAT12/16

数据区

(用于文件和目录)

 

需要说明的是:

1.引导扇区和其他保留扇区一起称为保留扇区,而其他保留扇区是可选的,当没有时候,引导扇区后紧跟的就是FAT1

2.根目录区是仅FAT12/16才有,FAT32的目录项位于数据区。由于FAT12/16的根目录区是一个固定的区域,所以它的根目录的项数是有限制的,意即不能在根录建立超过这个定数的目录项数。

(一)引导扇区与BPB

BPBBIOS Parametre Block)是FAT文件系统中第一个重要的数据结构,它位于该FAT分区的第一个扇区,同时也属于FAT文件系统基本区域的保留区,

 

       在下面的描述中。凡名称以BPB_开头的都是BPB的一部分,凡名称与BS_开头的项都是启动扇区的一部分,而不是属于BPB的内容,以下是启动扇区的结构

 

offsetbyte

长度(byte

描述

BS_jmpBoot

0x00

3

跳转指令,指向启动代码

BS_OEMName

0x03

8

建议值为“MSWIN4.1”。有些厂商的FAT驱动可能会检测此项,所以设为“MSWIN4.1”可以尽量避免兼容性的问题

BPB_BytsPerSec

0x0b

2

每扇区的字节数,取值只能是以下几种:51210242048或是4096。设为512会取得最好的兼容性,目前有很多FAT代码都是硬性规定每扇区的字节数为512,而不是实际的检测此值。但微软的操作系统能够很好支持10242048或是4096

BPB_SecPerClus

0x0d

1

每簇的扇区数,其值必须中2的整数次方(该整数必须>=0),同时还要保证每簇的字节数不能超过32K,也就是1024*32字节

BPB_RsvdSecCnt

0x0e

2

保留扇区的数目,此域不能为0FAT12/FAT16必须为1FAT32的典型值取为32,,微软的系统支持任何非0

BPB_BumFATs

0x10

1

分区中FAT表的份数,,任何FAT格式都建议为2

BPB_RootEntCnt

0x11

2

对于FAT12FAT16此域包含根目录中目录的个数(每项长度为32bytes),对于FAT32,此项必须为0。对于FAT12FAT16,此数乘以32必为BPB_BytesPerSec的偶数倍,为了达到更好的兼容性,FAT12FAT16都应该取值为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_FATz16

0x16

2

FAT12/FAT16一个FAT表所占的扇区数,对于FAT32来说此域必须为0,在BPB_FATZ32中有指定FAT表的大小

BPB_SecPerTrk

0x18

2

每磁道的扇区数,用于BIOS中断0x13,此域只对于有“特殊形状”(由磁头和柱面每分割为若干磁道)的存储介质有效,同时必须可以调用BIOS0x13中断得到此数值

BPB_NumHeads

0x1A

2

磁头数,用于BIOS0x13中断,类似于上面的BPB_ SecPerTrk,只对特殊的介质才有效,此域包含一个至少为1的数值,比如1,4M的软盘此域为2

BPB_HidSec

0x1C

4

在此FAT分区之前所隐藏的扇区数,必须使得调用BIOS0x13中断可以得到此数值,对于那些没有分区的存储介质,此域必须为0,具体使用什么值由操作系统决定

BPB_ToSec32

0x20

4

该卷总扇区数(32bit),这里的扇区总数包括FAT卷四个个基本分的全部扇区,此域可以为0,若此域为0BPB_ToSec16必须为非0,对FAT32,此域必须是非0。对于FAT12/FAT16如果总扇区数大于或等于0x10000的话,此域就是扇区总数,同时BPB_ToSec16的值为0

 

FAT32BPB的内容和FAT12/16的内容在地址36以前是完全一样的,从偏移量36开始,他们的内容有所区别,具体的内容要看FAT类型为FAT12/16还是FAT32,这点保证了在启动扇区中包含一个完整的FAT12/16FAT32BPB的内容,这么做是为了达到最好的兼容性,同时也为了保证所有的FAT文件系统驱动程序能正确的识别和驱动不同的FAT格式,并让他们良好地工作,因为他们包含了现有的全部内容

offset 36开始FAT12/FAT16的内容开始区别于FAT32,下面分两个表格列出,下表为FAT12/FAT16的内容

名称

offsetbyte

长度(byte

描述

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的内容

名称

offsetbyte

长度(byte

描述

BPB_FATSz32

0x24

4

一个FAT表所占的扇区数,此域为FAT32特有,同时BPB_FATSz16必须为0

BPB_Flags

0x28

2

此域FAT32特有。

Bits0-3:不小于0FATactive 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

保留区中FAT32FSINFO结构所占的扇区数,通常为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_FilSysType

0x47

11

FAT12/16的定义相同,只不过两者位于启动扇区不同的位置而已

BS_FilSysType

0x52

8

通常设置为“FAT32”,请参照FAT12/16此部分的陈述。

 

关于FAT启动扇区还有一点重要的说明,我们假设里面的内容是按字节排序的,那么扇区[510]的内容一定0x55,扇区[511]的内容一定是0xAA

很多FAT资数文档会把0xAA55说成是“启动扇区最后两字节的内容”,这样的陈述是正确的仅仅是如果—BPB_BytsPerSec的值为512的话。若BPB_BytsSec的值大于512,该标记的位置并没有改变(虽然在启动扇区的最后两个字节写0xAA55并没有问题)

关于BPB_ToSec16/32这里再作一点补充:假设一现在我们有一块磁盘或一个分区,它的扇区数为DskSz,如果BPB_aToSec(BPB_ToSec16或是BPB_ToSec32基中不为0的那个)的值小于或等于DskSz并不会使该FAT卷在使用中出现什么错误,实际上BPB_ToSec16/32的值不要比DskSz小得离谱就不会有什么错误

这样做将造成磁盘空间的浪费,程序本身并不会认为该FAT卷存在什么错误,但是,如果BPB_ToSec16/32的值比DskSz大将会使FAT卷遭到严重的损坏,因为它超出了存储介质或是磁盘分区的边界。当BPB_ToSec16/32的值比DskSz大时,一些数据将不幸地被丢失