最近在学习《一个64位操作系统的设计与实现》,书中bootloader采用fat12文件系统,而现在u盘、硬盘一般都是使用fat32文件系统,为了将bootloader迁移到fat32文件系统中,因此研究了一下fat32文件系统。
硬盘fat32文件系统结构
MBR: 硬盘的第一个扇区被保留为主引导扇区,它位于整个硬盘的0磁头0柱面1扇区,包括硬盘主引导记录MBR(Main Boot Record)和分区表DPT(Disk Partition Table)。其中主引导记录的作用就是检查分区表是否正确以及确定哪个分区为引导分区,并在程序结束时把该分区的启动程序(也就是操作系统引导扇区)调入内存加以执行。至于分区表,很多人都知道,以80H或00H为开始标志,以55AAH为结束标志,共64字节,位于本扇区的最末端。
DPT: 硬盘分区表,总共64字节,每个表项16字节,具体结构如下:
[0:0]字节:表示分区类型(00表示非活动分区;80表示活动分区;其他为无效分区)
[1:3]字节:表示分区的起始地址(磁头/扇区/柱面):通常第一分区的起始地址开始于1磁头0 柱面1扇区,因此这三个字节应为010100
[4:4]字节:表示常见的分区操作系统的类型(00 [none-use] 04 [DOS FAT16 <32M] 05 [EXTEND] 06 [DOS FAT16 >32M] 07 [NTFS (OS/2)] 0B [ FAT32] 83 [LINUX > 64M])
[5:7]字节:表示该分区的结束地址(磁头/扇区/柱面)
[8:11]字节:表示该分区起始逻辑扇区(在线性寻址方式下的分区相对扇区地址)
[12:15]字节:表示该分区占用的总扇区数
如上图所示,该硬盘只有一个分区,分区起始于0柱面1磁头2扇区,分区操作系统类型为0x0c,分区结束于255柱面254磁头255扇区,起始线性地址为64扇区,结束线性地址为0x03a97fc0扇区
DBR: 文件系统的引导扇区,根据前面参数可知在第64扇区,以0x55,0xaa结束,开始是文件系统的结构化参数,
jmp short Label_Start ; 跳转指令,后接一个空指令,3字节
nop
BS_OEMName db 'MINEboot' ; 生产厂商,8字节
BPB_BytesPerSec dw 512 ; 每扇区字节数,2字节
BPB_SecPerClus db 0x20 ; 每簇扇区数,文件系统管理单位,1字节
BPB_RsvdSecCnt dw 0x26 ; 保留扇区数,第一个为引导扇区,2字节
BPB_NumFATs db 2 ; FAT表的份数,1字节
BPB_RootEntCnt dw 0 ; 根目录可容纳的目录项数,2字节
BPB_TotSec16 dw 0 ; 总扇区数,2字节
BPB_Media db 0xf8 ; 介质描述符,1字节,硬盘为0xf8,软盘为0xf0
BPB_FATSz16 dw 0 ; 每FAT表占用扇区数,2字节
BPB_SecPerTrk dw 0x3f ; 每磁道扇区数,2字节
BPB_NumHeads dw 0xff ; 磁头数,2字节
BPB_HiddSec dd 0x40 ; 隐藏扇区数,4字节
BPB_TotSec32 dd 0x03a97fc0 ; 如果BPB_TotSec16为0,则由这个值记录扇区总数,4字节,C/H/S = 73/16/63
BPB_FATSz32 dd 0x3a91 ; 每个FAT表占用扇区数,4字节
BPB_Flags dw 0
BPB_FSVer dw 0
BPB_RootClus dd 2 ; 根目录的第一个簇的簇号,4字节
BPB_FSIfo dw 1 ; 保留区中FAT32卷FSINFO结构所占的扇区数,通常为1,2字节
BPB_BkBootSec dw 6 ; 如果不为0,表示在保留区中引导记录的备数据所占的扇区数,通常为6,2字节
BPB_Reserved times 12 db 0 ; 预留
BS_DrvNum db 0x80 ; int 13h的驱动器号,1字节
BS_Reserved1 db 0 ; 未使用,1字节
BS_BootSig db 29h ; 扩展引导标记,1字节
BS_VolID dd 0xc65bb56d ; 卷序列号,4字节
BS_VolLab db 'boot loader' ; 卷标,11字节
BS_FileSysType db 'FAT32 ' ; 文件系统类型,8字节
后面是引导程序和结束标志
保留扇区:FAT32在保留区中增加了一个FSINFO扇区,用以记录文件系统中空闲簇的数量以及下一可用簇的簇号等信息,以供操作系统作为参考。FSINFO信息扇区一般位于文件系统的1号扇区,结构比较简单。
FAT1:主文件分配表,起始于第102扇区(隐藏扇区(包含MBR)64+保留扇区(BPB_RsvdSecCnt)38 = 102)
第0项一般为0x0ffffff8,f8和BPB_Media一致,第1项一般为0xffffffff,前两项不可用,0x0fffffff表示文件结束,否则记录文件的下一个簇编号,一个簇可能是多个扇区,4KB对齐的硬盘一个簇就是8个扇区
FAT2: 副文件分配表,FAT1的备份,起始于第15095扇区(BPB_FATSz32=0x3a91(14993), 102 + 14993 = 15095)
根目录扇区:存放文件目录信息,起始于第30088扇区(15095 + 14993 +(BPB_RootClus - 2)× BPB_SecPerClus),前两个簇不能使用,因此根目录起始簇要减2,每项32字节
上图中kernel.bin文件的第一个簇为9,查FAT1可得下一个簇为0xa,直到查找到0x0fffffff
电脑启动时,先加载第一个扇区也就是MBR到0x7c00,然后从0x7c00开始执行,MBR中程序会将自己拷贝到其它地址执行,然后找到第一个活动分区,然后加载活动分区的第一个扇区到0x7c00,继续从0x7c00开始执行