分区结构
DBR,引导记录区,包括一个引导程序和一个BPB,即本分区参数记录表
系统可直接访问的第一个扇区,大小为512个字节(特殊情况占用其他保留扇区)
512字节中,由跳转指令,厂商标志,操作系统版本号,BPB,拓展BPB,os引导程序,结束标志几个部分组成
引导程序的主要任务是当MBR将系统控制权交给 引导程序 时,判断本分区根目录的前两个文件是不是操作系统的引导文件
如果确定存在,将引导文件读入内存,并将控制权交给这个引导文件
BPB参数记录本分区的起始扇区,结束扇区,文件存储格式,硬盘介质描述符,根目录大小,FAT个数,分配单元的大小等参数
扩展分区中存在一个类似MBR的扩展引导记录EBR
扩展引导记录包括一个扩展分区表和该扇区的标签
扩展引导记录记录只包含扩展分区中每个逻辑驱动器的第一个柱面的第一面的信息
如果磁盘上没有扩展分区,就不会有扩展引导记录和逻辑驱动器
DBR
DBR,引导记录区,由两部分构成,引导代码,以及BPB,总大小为 0x0200 字节
BPB,分区引导记录,是FAT文件系统中的第一个重要的数据结构,位于FAT分区的起始位置
/***************************************************************************************
* FAT32文件系统
* 0x00~0x02:3个字节的跳转指令
* 0x03~0x0A:8个字节的文件系统标志和版本号,比如MSDOC5.0
* 0X0B~0X0C:2个字节,每个扇区包含多少字节
* 0x0D~0x0D:1个字节,每个簇有多少扇区(Block)
* 0x0E~0x0F:2个字节,保留扇区数量
* 0X10~0X10:1个字节,FAT表个数
* 0x11~0x12:2个字节,根目录最多可容纳的目录下数,FAT12/16常为512,FAT32则不使用此值
* 0x12~0x14:2个字节,扇区的总数量;小于32Mb使用该位置存放,超过32M(不使用此处)使用偏移0x20~0x23这4个字节存放
* 0x15~0x15:1个字节,介质描述符
* 0x16~0x17:2个字节,每个FAT表的带下扇区数(FAT32不使用)
* 0x18~0x19:2个字节,每磁道有多少扇区
* 0x1A~0x1B:2个字节,磁头数
* 0x1C~0x1F:4个字节,分区之前已经使用扇区数量(若无分区,为相对于MBR的地址偏移量,MBR的扇区地址才是整个SD卡的物理扇区号为0的那个地址;文件系统并不处于SD卡最开始的地方,而是MBR保留区之后)
* 0x20~0x23:4个字节,文件系统有多少扇区
* 0x24~0x27:4个字节,每个FAT表占据多少扇区
* 0x28~0x29:2个字节,标记
* 0x2A~0x2B:2个字节,版本号
* 0x2C~0x2F:4个字节,根目录簇号(FAT32下,根目录可以存放在数据区的任何位置,多数情况根目录还是起始于2号簇)
* 0x30~0x31:2个字节,文件系统信息扇区扇区号,该扇区为操作系统提供关于空出总数以及下一可用簇的信息
* 0x32~0x33:2个字节,备份引导扇区的位置(簇号)
* 0x34~0x3F:12个字节,未使用
* 0x40~0x40:1个字节,BIOS INT 13H,设备爱好
* 0x41~0x42:1个字节,未使用
* 0x42~0x42:1个字节,扩展引导标志
* 0x43~0x46:1个字节,卷序列号,多为一个随机值
* 0x47~0x51:11个字节,卷标,如果建立文件系统的时候指定了卷标就会保存在此
* 0x52~0x59:8个字节,文件系统格式的ASCII码,FAT32
* 0x5A~0x1FD:410个字节,为使用(不固定)
* 0x1FE~0x1FF:结束标志
*************************************************************************************/
FAT16 DBR
1、跳转指令,跳转指令占用2字节,跳转执行指令占一个字节
EB 3C 90 ; EB -> jmp
jmp NOP ; 实际跳转执行 0x02 + 0x3C,即 0x3E 地址的代码,本身占两个字节
2、OEM代码,占8个字节,说明当前的操作系统版本
3、BPB,分区引导记录,BPB从DBP的第12个字节开始,占用51个字节,记录了各种数据参数(从0x0B开始)
4、引导程序,DBR程序站448个字节,负责将系统文件 NTLDR 装入,对于没有操作系统的分区而言,这段代码没有作用
字节偏移 | 字段长度 | 字段名与定义 | |
---|---|---|---|
0x0B | 2 | 单个扇区大小 | 0x0200 512个字节 |
0x0D | 1 | 单个簇占多少扇区 | 0x04,单个簇2KB,4个扇区 |
0x0E | 2 | DBR到FAT有多少扇区 | |
0x10 | 1 | FAT个数 | 0x02,一个使用,一个备份 |
0x11 | 2 | 根目录可容纳最大目录项数 | |
0x13 | 2 | 扇区总数 | |
0x15 | 1 | 介质描述符 | 0xF8,根据磁盘属性取不同值 |
0x16 | 2 | 每个FAT表多有大,扇区 | |
0x18 | 2 | 每个磁道扇区数量 | 0x003F,单个磁道63个扇区 |
0x1a | 2 | 磁头数量 | 0x00FF,255个磁头 |
0x1c | 4 | 隐藏扇区数 | 0x0000 0800,MBR到DBR之间的扇区数量,扩展分区则是EBR到DBR |
0x20 | 4 | 该分区扇区总数 | 0x0004 3800,分区共计276480个扇区,包含DBR与保留扇区 |
0x24 | 1 | BIOS驱动器号 | |
0x25 | 1 | 未使用 | |
0x26 | 1 | 扩展引导标号 | |
0x27 | 4 | 卷序列号 | |
0x2B | 11 | 卷标 | |
0x36 | 8 | 文件系统类型 |
FAT32 DBR
1、跳转指令,跳转指令占用2字节,跳转执行指令占一个字节
EB 58 90 ; EB -> jmp
jmp NOP ; 实际跳转执行 0x5A 地址的代码,本身占两个字节
2、OEM代码,占8个字节,说明当前的操作系统版本
3、BPB,分区引导记录,BPB从DBP的第12个字节开始,占用79个字节,记录了各种数据参数(从0x0B开始)
4、引导程序,DBR程序占420个字节,负责将系统文件 NTLDR 装入,对于没有操作系统的分区而言,这段代码没有作用
字节偏移 | 字段长度 | 字段名与定义 | |
---|---|---|---|
0x0B | 2 | 单个扇区大小 | 0x0200 512个字节 |
0x0D | 1 | 单个簇占多少扇区 | 0x04,单个簇2KB,4个扇区 |
0x0E | 2 | DOS保留扇区数量 | 0x1BE6 个保留扇区,DBR到FAT1表之间的扇区数,FAT1起始扇区号 |
0x10 | 1 | FAT个数 | 0x02,一个使用,一个备份 |
0x11 | 2 | 未使用 | 0x0000 |
0x13 | 2 | 未使用 | 0x0000 |
0x15 | 1 | 介质描述符 | 0xF8,根据磁盘属性取不同值 |
0x16 | 2 | 未使用 | 0x0000, |
0x18 | 2 | 每个磁道扇区数量 | 0x003F,单个磁道63个扇区 |
0x1a | 2 | 磁头数量 | 0x00FF,255个磁头 |
0x1c | 4 | 隐藏扇区数 | 0x0000 0800,MBR到DBR之间的扇区数量,扩展分区则是EBR到DBR |
0x20 | 4 | 该分区扇区总数 | 0x0004 3800,分区共计276480个扇区 |
0x24 | 4 | 每个FAT对应几个扇区 | 0x0000 020D,一个FAT表占 525 个扇区 |
0x28 | 2 | 标志 | 0x0000,FAT2可否使用,0x02为可使用 |
0x2A | 2 | 版本 | 0x0000,通常为0 |
0x2C | 4 | 根目录首簇号 | 0x0000 0002,首簇和第一簇均被使用,从第二簇开始 |
0x30 | 2 | 文件系统信息扇区号 | 0x0001 |
0x32 | 2 | DBR备份扇区号 | 0x0006,DBR的备份,一般位于6号扇区,第7个扇区 |
0x34 | 12 | 保留 | |
0x40 | 1 | BIOS驱动器号 | 0x80,BIOS描述的设备号,硬盘为 0x8x |
0x41 | 1 | 未用 | 0x00 |
0x42 | 1 | 扩展引导标记 | 0x29,确认后面3个参数是否有效,值为 0x29 |
0x43 | 3 | 卷序列号 | 0x5EF3 B24E |
0x47 | 11 | 卷标 | |
0x52 | 8 | 文件系统类型 | FAT32 |
FAT32 文件系统在 DBR 的保留扇区中,有安排一个文件系统信息扇区
DBR 保留扇区用于记录数据区中空闲簇的数量,以及下一个可用空闲簇的簇号,扇区一般在分区的1号扇区,紧跟DBR之后
保留扇区
字节偏移 | 字段长度 | 字段名与定义 | |
---|---|---|---|
0x00 | 4 | 扩展引导标签,52 52 61 41,RRaA | 52 52 61 41 |
0x04 | 480 | 未使用 | 全为0 |
0x01E4 | 4 | 文件系统签名,72 72 41 61,rrAa | 72 72 41 61 |
0x01E8 | 4 | 空闲簇数 | 0x0001 05FD,67069个空闲扇区 |
0x01EC | 4 | 下一个空闲簇号 | 0x0000 0005,下一可用空闲簇为5号簇 |
0x01F0 | 14 | 未使用 | 全为0 |
0x01FE | 2 | 结束标志,55 AA | 55 AA |
FAT表
FAT,File Allocation Table,文件分配表,分配表中内含表项
文件在占用磁盘空间时,基本单位不是字节而是簇,簇的大小与磁盘规格有关,一般软盘的一个簇就是一个扇区,硬盘的一个簇可能是4个扇区,8个扇区
同一个文件的数据并不是完整的存放在磁盘的一个连续区域内,而是分为若干段,存储在不同区域内,呈链式存储
硬盘上的文件需要创建,删除,增长,缩短操作,操作越多,文件就可能被分得越零碎,每段至少占一个簇
而由于FAT的存在,操作系统读取文件时,总是可以准确读取找到各段位置,并且正确读取
这种以簇为单位的存储方式,一个文件最少占据一个簇,在文件比较少的时候会浪费内存
FAT起始地址:DBR起始地址 + 保留扇区数量
其中0号和1号表项被系统保留存储特殊标志内容,所以对应的0和1号簇不能使用
其中第0个簇和第1个簇,两个簇默认系统使用,不允许被使用,只能从第2个簇开始使用
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
7468500000 EB 58 90 4D 53 44 4F 53 35 2E 30 00 02 04 E6 1B .X.MSDOS5.0..... // DBR起始地址,7468500000,保留扇区数量 0x1BE6
7468500010 02 00 00 00 00 F8 00 00 3F 00 FF 00 00 08 00 00 ........?.......
7468500020 00 38 04 00 0D 02 00 00 00 00 00 00 02 00 00 00 .8.............. // FAT 大小 0x0000 020D 个扇区
7468500030 01 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ // 即 FAT1起始地址 746887CC00,FAT2起始地址 74688BE600
746887CC00 F8 FF FF 0F FF FF FF FF FF FF FF 0F FF FF FF 0F ................ // FAT1区域,簇0 0x0FFF FFF8,簇1 0xFFFF FFFF 两个不可用
746887CC10 FF FF FF 0F FF FF FF 0F FF FF FF 0F FF FF FF 0F ................ // 簇1 0x0FFF FFFF, ... ... ,簇8 0x0FFF FFFF,结束符
746887CC20 FF FF FF 0F FF FF FF 0F 00 00 00 00 00 00 00 00 ................
746887CC30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
74688BE600 F8 FF FF 0F FF FF FF FF FF FF FF 0F FF FF FF 0F ................
74688BE610 FF FF FF 0F FF FF FF 0F FF FF FF 0F FF FF FF 0F ................
74688BE620 FF FF FF 0F FF FF FF 0F 00 00 00 00 00 00 00 00 ................
74688BE630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
为了实现文件的链式存储,必须记录哪些簇被占用,并且为已经被占用给的簇指明存储接下来数据的簇(簇2使用,表示数据区 第一个 簇被使用)
对于文件的最后一个簇,要指明这个簇后面再无后继簇(0x0FFF FFFF表示文件结束符)
这些都是由 FAT 表来保存的,表中有很多表项,每项记录一个簇的信息
FAT区域会有一个备份,即在原 FAT 的后面再建一个同样的FAT,用于备份数据
初次建立的 FAT ,所有表项标识为未使用,如果磁盘有局部损坏,格式化程序会检测到损坏的簇,在相应的项中标为坏簇,存储文件不会再使用这个簇
FAT 的项数与硬盘上的总簇数相当,每一个 FAT 占用的字节数要与总簇数相适应,因为 FAT表 中簇对应地址,
// 簇0对应区域: DBR起始地址 + 保留扇区大小 + FAT1大小 + FAT2大小
7468500000 + 0x1BE6 * 0x200 + 0x020D * 2 * 0x200 = 7468900000 // 这个地址是根目录区,FDT,也是为什么 簇1和簇2 不允许使用
// 可从簇从出2开始,则可用地址
7468500000 + 0x1BE6 * 0x200 + 0x020D * 2 * 0x200 + 0x200 * 4 * 2 = 7468910000 // 前提是簇1类型非目录或其他,而是文件
FAT 的格式有很多种,最常见的是 FAT32 ,FAT16 指文件分配表使用16位数字,16位分配表最多可管理65536个簇,也就是规定的一个硬盘分区
每个簇的存储空间最大为32KB,在使用 FAT16 管理硬盘时,每个分区最大存储容量为 65535 * 32KB = 2GB
使用 FAT32 标准,分区容量最大可达 65GB 以上
由于FAT表项中的0和1号表项被使用,不与任何簇对应,所以簇号起始与2号;FAT32的0号表项值总是0xF8FF FF0F
从2号地址开始,每个地址对应于数据区的簇号,FAT表中的地址标号与数据区中的簇号相同,
如果某个簇未被使用,则对应的FAT表项中的FAT表项值用0填充,表示其未被使用
当这个簇被使用,其对应的FAT表项中的表项值就是这个文件的下一个存储位置的簇号;如果文件结束于这个簇,则起对应表项中记录的是一个文件结束标记
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
746887CC00 F8 FF FF 0F FF FF FF FF FF FF FF 0F FF FF FF 0F ................
746887CC10 FF FF FF 0F FF FF FF 0F FF FF FF 0F 00 00 00 00 ................
746887CC20 FF FF FF 0F FF FF FF 0F 0B 00 00 00 0C 00 00 00 ................ // 头两个文件为结束簇,接下来指示 整个文件使用 26 个簇,52k
746887CC30 0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00 ................
746887CC40 11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00 ................
746887CC50 15 00 00 00 16 00 00 00 17 00 00 00 18 00 00 00 ................
746887CC60 19 00 00 00 1A 00 00 00 1B 00 00 00 1C 00 00 00 ................
746887CC70 1D 00 00 00 1E 00 00 00 1F 00 00 00 20 00 00 00 ............ ...
746887CC80 21 00 00 00 22 00 00 00 23 00 00 00 FF FF FF 0F !..."...#.......
7468900100 43 6B 00 64 00 68 00 6B 00 73 00 0F 00 B7 6A 00 Ck.d.h.k.s....j. // FDT部分
7468900110 68 00 61 00 2E 00 63 00 00 00 00 00 FF FF FF FF h.a...c.........
7468900120 02 6B 00 61 00 73 00 68 00 6A 00 0F 00 B7 64 00 .k.a.s.h.j....d.
7468900130 68 00 6A 00 6B 00 61 00 73 00 00 00 68 00 6A 00 h.j.k.a.s...h.j.
7468900140 01 73 00 61 00 6F 00 68 00 64 00 0F 00 B7 73 00 .s.a.o.h.d....s.
7468900150 64 00 6A 00 6B 00 73 00 61 00 00 00 68 00 6A 00 d.j.k.s.a...h.j.
7468900160 53 41 4F 48 44 53 7E 31 43 20 20 20 00 9C 30 76 SAOHDS~1C ..0v
7468900170 C2 50 C2 50 00 00 DA 8B C2 50 0A 00 09 CC 00 00 .P.P.....P...... // 文件使用的簇号为 0x0000 000A,文件大小 0x0000 CC09,51kb+
// 分配的最小单位为1簇,2KB,所以必须分配26个簇
7468904000 4F 66 66 73 65 74 20 20 20 20 20 20 20 20 30 20 Offset 0 // 起始地址7468900000 + (0x0A - 2) * 0x800 = 74689004000
7468904010 20 31 20 20 32 20 20 33 20 20 34 20 20 35 20 20 1 2 3 4 5
7468904020 36 20 20 37 20 20 38 20 20 39 20 20 41 20 20 42 6 7 8 9 A B
7468904030 20 20 43 20 20 44 20 20 45 20 20 46 20 20 30 31 C D E F 01
7468904040 32 33 34 35 36 37 38 39 41 42 43 44 45 46 0D 0A 23456789ABCDEF..
7468904050 0D 0A 37 34 36 38 39 30 30 31 30 30 20 20 20 34 ..7468900100 4
7468904060 33 20 36 42 20 30 30 20 36 34 20 30 30 20 36 38 3 6B 00 64 00 68
文件系统中,新建文件只占一个簇,则对应簇的FAT表项中将写入结束标志
如果占据多个簇,则每个簇对应的FAT表项中写入的都是文件下一段的簇号,在最后一簇的FAT表项中写入结束标志
文件的起始簇号记录在对应的目录项中,文件的其他簇用一个簇链结构记录在FAT表中
要寻找文件的下一个簇,只需要查找文件的目录下中描述的起始簇号对应到的FAT表项
如果文件大小不止一个簇,则这个FAT表项记录的就是下一簇的簇号;否则就是结束标记
对于FAT32 = BPB_FATSz32 * 512 / 4,由FAT表占据的字节数除以4,获取FAT表项的个数
(0x020D * 0x200 / 4) * 2 = 1334400KB = 131MB,保留扇区大小4MB // 已证实无误
FAT取值
0号表项值总为 0x0FFF FFF8,1号表项值记录脏标志,寿命文件系统没有被正常卸载,或者磁盘表存在错误,一般是 0xFFFF FFFF 或 0xFFFF FF0F
FAT12取指 | FAT16取指 | FAT32取指 | 描述 |
---|---|---|---|
0x000 | 0x0000 | 0x0000 0000 | 未分配的簇 |
0x002 ~ 0xFEF | 0x0002 ~ 0xFFEF | 0x0000 0002 ~ 0x0FFF FFEF | 已占用的簇,指向文件地址 |
0xFF0 ~ 0xFF6 | 0xFFF0 ~ 0xFFF6 | 0x0FFF FFF0 ~ 0x0FFF FFF6 | 系统保留 |
0xFF7 | 0xFFF7 | 0x0FFF FFF7 | 簇损坏标识 |
0xFF8 ~ 0xFFF | 0xFFF8 ~ 0xFFFF | 0x0FFF FFF8 ~ 0x0FFF FFFF | 文件结束簇 |
DATA
数据区紧接在 FAT2区域后,即可通过 DBR 起始字节 + DOS保留扇区 * 扇区大小 + FAT大小 * 2
通过这个公式可获得DATA区域的起始字节
FDT位于DATA区域的起始位置,即获取的DATA起始位置就是FDT的起始字节
FDT
为什么FAT区域的首两个簇不可使用?因为这两个簇相当于 管理 FDT ,即 FDT 区域大小为两个簇
FDT表,也就是文件目录表,也叫做根目录区或者ROOT区
用格式化命令对硬盘进行格式化时,已经为整个硬盘建立了根目录FDT
FDT位于第二个FAT表后,DATA区域的起始位置,只有当FAT表不能定位文件在硬盘中位置的时候,FAT才和FDT配合准确定位文件位置
FDT中存储的是
文件目录项
,目录项包含文件,文件夹;文件目录中存储的是文件名,文件起始簇号,文件长度等基本信息
FAT32 文件系统中,根据结构不同,可将目录项大致分为4种,卷标目录项,.目录项,…目录项,短文件名目录项,长文件名目录项
短文件名目录项是最重要的数据结构,里面存放着有关子目录或文件的短文件名,属性,起始簇号,事件值以及内容大小等信息
在 FAT32 文件系统中,将子目录看作是一种特殊的文件
短文件名目录项
记录的文件名为8个字符的名字,外加3个字符的扩展名
如果文件名不足8个字节,用 0x20 进行填充
超过8个字符时会被截断,短文件名目录项中没有足够的空间记录超出部分,截断方法是取文件名的前6个字节加上~1,有同名文件则递增,外加扩展名
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
7468900160 53 41 4F 48 44 53 7E 31 43 20 20 20 00 9C 30 76 SAOHDS~1C ..0v // 此处被截断,截断方式 文件名前6个字节 + ~1,C为扩展文件名
如果是子目录,扩展名部分用 0x20 进行填充
为了解决长文件名的问题,FAT 文件系统增加了长文件名目录项结构,不论文件名长度是否超过8个字符,都会为其创建短文件名和长文件名目录项,因为短文件名不区分大小写,长文件名区分大小写
特性
每个文件或子目录都分配有1个32字节的目录下,用于描述文件或目录的属性
所有的目录项地址并不相同,要找到目录项的位置,只能用分配给文件或子目录的全名进行搜索
目录项结构中有一个属性区域,每个文件可设置7种属性
每个文件或目录还有4个非关键属性,只读,隐藏,系统,存档
每个目录项包括3个事件值,建立时间,最后访问时间,最后修改时间
一个目录项是否被分配使用它的第一个字节来描述,对于已经分配使用的目录下,其第一个字节是文件名的第一个字符,文件或目录被删除后,对应的目录下的第一个字节将被置为 0xE5,这是为什么有的 FAT 数据恢复工具需要用户自己输入文件名的第一个字符
每个段文件名目录下占32个字节,数据结构如下图所示
需要注意的一点,这里的文件位置簇,指的是 文件使用 FAT 区域的几号簇,而不是文件在数据区的地址
0x0E~0x0F: 0~4bit为秒,以2秒为单位
5~10bit为分
11~15bit为时
短文件名目录项中,不允许出现小写字母,即使文件名是小写字母,在短文件名目录项中,也是以大写形式出现的,并且不记录文件名和扩展名之间的.
0x00偏移位置的取值若为0x00,则表示目录项为空;若为0xE5,则表示目录项被使用过,但是对应的文件或者目录项已经被删除(误删后恢复)
文件名中第一个字符为.或者..,表示这个簇记录的是一个子目录的目录下
长文件名目录项
文件系统在为文件创建长文件名类型(Long File Name,LFN)的目录项时,并没有舍弃原有的短文件名目录项,具有 LFN 的文件同时也有一个常规的 SFN,short file name,即短文件名类型目录项
之所以需要 SFN ,因为 LFN 目录项只包含文件的名字,不包括任何相关时间,大小以及起始簇号等信息,这些信息仍需要 SFN 目录项来记录
特性
如果一个文件的文件名超过 8 个字符,则会为其名字截断后再为其创建短文件名
将短文件名存储在短文件名目录项中,长文件名存放在长文件名目录项中
LFN 和 SFN 目录项结构在相同位置有一个树形标志字节,LFN目录项使用一个特定的属性值,说明其是一个长文件名项
LFN 目录项中的其他字节,使用 UTF-16 存储13个 Unicode 字符的文件名,每个字符占用2个字节
如果文件名长于13个字节,继续为其分配 LFN 项,直到够用位置
所有 LFN 都包含一个校验和,通过这个校验和将其与相应的 SFN 项关联
一个文件的所有 LFN 向按倒叙排列在其 SFN 项前面,即文件名的第一部分距离 SFN 最近
也就是一个文件名很长的文件,短目录项存储文件属性与部分文件名,长文件名存储剩余文件名
一个文件的第一个长文件名序列号为1,然后依次递增(多个长文件名目录项时),该文件的最后一个长文件名目录项,将其序号与0x40进行或运算后,值写入这个位
对应的文件或子目录被删除,该自己设置为0xE5
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
74689000E0 E5 41 4F 48 44 53 7E 31 43 20 20 20 00 9C 30 76 .AOHDS~1C ..0v // 0xE5 表示被删除,0x20表示为归档
74689000F0 C2 50 C2 50 00 00 31 76 C2 50 00 00 00 00 00 00 .P.P..1v.P......
7468900100 43 6B 00 64 00 68 00 6B 00 73 00 0F 00 B7 6A 00 Ck.d.h.k.s....j. // 0x43 0100 0011,长文件最后一个记录
7468900110 68 00 61 00 2E 00 63 00 00 00 00 00 FF FF FF FF h.a...c......... // 未使用字节填充 FF,0x1c~0x1F
7468900120 02 6B 00 61 00 73 00 68 00 6A 00 0F 00 B7 64 00 .k.a.s.h.j....d. // 0x02,长文件第二个记录
7468900130 68 00 6A 00 6B 00 61 00 73 00 00 00 68 00 6A 00 h.j.k.a.s...h.j.
7468900140 01 73 00 61 00 6F 00 68 00 64 00 0F 00 B7 73 00 .s.a.o.h.d....s. // 0x01,长文件第一个记录,类型 0x0F,长文件类型
7468900150 64 00 6A 00 6B 00 73 00 61 00 00 00 68 00 6A 00 d.j.k.s.a...h.j.
7468900160 53 41 4F 48 44 53 7E 31 43 20 20 20 00 9C 30 76 SAOHDS~1C ..0v // 短文件记录,类型 0x20,归档文件
7468900170 C2 50 C2 50 00 00 31 76 C2 50 00 00 00 00 00 00 .P.P..1v.P...... // 此时文件内没有任何内容,所有没有分配空间
7468900160 53 41 4F 48 44 53 7E 31 43 20 20 20 00 9C 30 76 SAOHDS~1C ..0v // 当前已经填充字节,0x14~0x15,0x1A~0x1B有数据
7468900170 C2 50 C2 50 00 00 4E 78 C2 50 07 00 D0 02 00 00 .P.P..Nx.P...... // 偏移簇 0x0007,文件起始于7号簇,(7 - 2) * 簇大小
// 7468900000 + 5 * 0x800(2Kb) = 0x746890 2800
如果在创建文件系统的时候有设置卷标,会在根目录下为其建立卷标目录项,这个目录项占用根目录中的第一个目录项位置
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
7468900000 D0 C2 BC D3 BE ED 20 20 20 20 20 08 00 00 00 00 ...... ..... // 类型0x08 表示卷标
7468900010 00 00 00 00 00 00 16 76 C2 50 00 00 00 00 00 00 .......v.P...... // 此部分为 DATA 区域起始,FDT区域
.目录项和…目录项
一个子目录的数据区起始位置,固定存储两个目录项, . 和 … 目录项,子目录通过这两个目录项以及其在父母路子中的目录项,建立父子目录的联系
.目录项位于子目录起始簇的第一个目录项位置,用于标明簇是一个子目录的起始簇
目录项实际是堆目录自身的描述,记录了子目录时间信息,起始簇号,起始簇号也是子目录目前所处位置
…目录位于子目录起始簇的第二个目录项位置,用于描述子目录的父目录的相关信息
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF // 以下为 文件夹内部 数据
7468903000 2E 20 20 20 20 20 20 20 20 20 20 10 00 AB B7 82 . ..... // 。文件目录项,起始地址 8 号簇,即 7468903000
7468903010 C2 50 C2 50 00 00 B8 82 C2 50 08 00 00 00 00 00 .P.P.....P...... // 子目录指明自己,..目录项指明父目录
7468903020 2E 2E 20 20 20 20 20 20 20 20 20 10 00 AB B7 82 .. ..... // .。文件目录项,起始地址 0 号簇,即 7468900000
7468903030 C2 50 C2 50 00 00 B8 82 C2 50 00 00 00 00 00 00 .P.P.....P......