1. TF卡空间是如何分配的?
下面以4GB TF卡为例,通过WinHex工具进行分析,其空间分配如下图所示:
FAT32把目录当做文件来管理,所以没有独立的目录区,所有的文件目录项都是在数据区里面的。
2. 启动扇区 (DBR)
DBR(DOS BOOT RECORD,DOS引导记录),位于柱面0,磁头1,扇区1,即逻辑扇区0 ;
DBR包括:
• 一个引导程序: DOS 引导程序完成DOS系统文件(IO.SYS,MSDOS.SYS)的定位与装载
• 一个BPB: BPB用来描述本DOS分区的磁盘信息,比如:本分区的起始扇区、 结束扇区等等
注意:搜索DBR的标志:
• FAT16的DBR:EB 3C 90,无备份的DBR
• FAT32的DBR:EB 58 90,有备份的DBR,通常在该分区的第6扇区
• NTFS的DBR: EB 52 90,有备份的DBR,通常在该分区的最后一个扇区
2.1 DBR组成
偏移量 | 长度/字节 | 组成部分 |
00H | 3 | 跳转指令 |
03H | 8 | 操作系统厂商标识及版本号 |
08H | 80 | 分区参数表(又称BPB),里面存放着对该分区进行读写操作时所必备的参数 |
5AH | 420 | DOS引导代码,它负责把DOS引导文件IO.SYS、MSDOS.SYS装入内存 |
FEH | 2 | 结束标志字”55AA” |
2.2 BPB(BIOS Parameter Block)的组成
3. FAT(File Allocation Table)文件分区表
• 簇(Cluster)
是文件数据区被划分成的具有大小相等的区域用于磁盘文件的计量分配单位。
• 文件分配表
是位于磁盘0扇区上的一个特殊的文件,它包含了磁盘上的文件的大小以及文件存放的簇的位置等信息。
• 文件的首簇号
存放在FDT(根目录)登记项中,后续簇号存放在FAT中。
FAT表以簇为单位,标识分区中空间的使用情况(每个标识占4字节)。其示意图如下图所示:
FAT前2簇为保留簇(簇0和簇1),不分配给文件使用,其内容含义如下所示:
• FAT16:F8 FF FF
• FAT32:F8 FF FF 0F FF FF FF FF
一个FAT表项值表明了文件占用的一个簇号并指明下一簇号的位置。
FAT表按顺序依次记录了该盘各簇的使用情况,是一种位示图法。每簇的使用情况用32位二进制填写,未被分配的簇相应位置写零;坏簇相应位置填入特定值;已分配的簇相应位置填入非零值,具体为:如果该簇是文件的最后一簇,填入的值为FFFFFF0FH(即0x0FFFFFFF),如果该簇不是文件的最后一簇,填入的值为该文件占用的下一个簇的簇号,这样,正好将文件占用的各簇构成一个簇链,保存在FAT表中。0000000H、00000001H两簇号不使用,其对应的两个DWORD位置(FAT表开头的8个字节)用来存放该盘介质类型编号。
FAT表的大小就由该逻辑盘数据区共有多少簇所决定,取整数个扇区。
当文件系统被创建,也就是进行格式化操作时,分配给FAT区域的空间将会被清空,在FAT1与FAT2的0号表项与1号表项写入特定值。由于创建文件系统的同时也会创建根目录,也就是为根目录分配了一个簇空间,通常为2号簇,所以2号簇所对应的2号FAT表项也会被写入一个结束标记,如上图所示。
当某个簇已被分配使用时,则它对应的FAT表项内的FAT表项值也就是该文件的下一个存储位置的簇号。如果该文件结束于该簇,则在它的FAT表项中记录的是一个文件结束标记,对于FAT32而言,代表文件结束的FAT表项值为0x0FFFFFFF。
如果某个簇存在坏扇区,则整个簇会用FAT表项值0xFFFFFF7标记为坏簇,不再使用,这个坏簇标记就记录在它所对应的FAT表项中。
在文件系统中新建文件时,如果新建的文件只占用一个簇,为其分配的簇对应的FAT表项将会写入结束标记。如果新建的文件不只占用一个簇,则在其所占用的每个簇对应的FAT表项中写入为其分配的下一簇的簇号,在最后一个簇对应的FAT表象中写入结束标记。
新建目录时,只为其分配一个簇的空间,对应的FAT表项中写入结束标记。当目录增大超出一个簇的大小时,将会在空闲空间中继续为其分配一个簇,并在FAT表中为其建立FAT表链以描述它所占用的簇情况。
对文件或目录进行操作时,他们所对应的FAT表项将会被清空,设置为0以表示其所对应的簇处于未分配状态。
4. FDT (File Directory Table) 文件目录表
• 8--10字节: 文件扩展名。
• 12--13:字节仅长文件名目录项用,用来存储其对应的短文件名目录项的文件名字节校验和等。
• 14--15:字节 24位二进制的文件建立时间,其中的高5位为小时,次6位为分钟。
• 16--17字节:16位二进制的文件建立日期,其中的高7位为相对于1980年的年份值,次4位为月份,后5位为月内日期。
• 18--19字节: 16位二进制的文件最新访问日期,定义同(6)。
• 20--21字节 起始簇号的高16位。
• 22--23字节 16位二进制的文件最新修改时间,其中的高5位为小时,次6位为分钟,后5位的二倍为秒数。
• 24--25字节 16位二进制的文件最新修改日期,定义同(6)。
• 26--27字节 起始簇号的低16位。
• 28--31字节 32位的文件字节长度。
4.1 删除文件之后的变化
• 同时,将FAT文件分配表相应的项目清空,供其它程序使用
• 文件的数据并没有被覆盖,而是实际存在,但对操作系统而言,是无效的垃圾数据
• 当新文件需要存放时,新的数据可直接在原来数据位置上写入
4.2 根目录(root)
4.2.1 定位根目录
要想定位一个FAT32文件系统的数据起始处,可以通过引导扇区的相关参数计算出来。
保留扇区数+ 每个FAT表大小扇区数 × FAT表个数 = 数据区起始扇区号
要想计算其它已知簇号的扇区号,还要由引导扇区的偏移0x0D字节处查找到每个簇大小扇区数,并使用如下公式计算:
某簇起始扇区号 = 保留扇区数 + 每个FAT表大小扇区数 × FAT表个数 + (该簇簇号 - 2) × 每簇扇区数
4.2.2 根目录分析
文件系统刚被创建时,还没有存储任何数据时,根目录下没有任何内容,文件系统只是为根目录分配了一个簇的空间(通常为2号簇),将结束标记写入该簇对应的FAT表项,表示该簇已经被分配使用。这时候,为根目录分配的空间没有任何内容。但如果在创建文件系统的时候是定了卷标,则会在根目录下为其建立一个卷标目录项,该目录项占用根目录中的第一个目录项位置。
不管是根目录还是子目录下的目录项,都具有以下的基本特性:
1) 为文件或子目录分配的第一个簇的簇号记录在它的目录项中,其他后续簇则由FAT表中的FAT表链进行跟踪。
2) 目录项中除记录子目录或文件起始簇号外,还记录它的名字、大小(子目录没有大小)、时间值等信息。
3) 每个子目录或文件除具有一个短文件目录项外,还会有长文件名目录项。
4) 短文件名目录项固定占用32字节,长文件名目录项则根据需要占用1个或者若干个32字节。
5) 对于同一个子目录或文件,它的长文件名目录项存放在它的短文件名目录项之前,如果长文件名目录项占用多个32字节,则按倒序存放于段文件名目录项之前。