优盘上的数据按照其不同的特点和作用大致可分为 5 部分:MBR 区、DBR 区、FAT 区、FDT区和 DATA区。
主引导记录(MBR)
绝对扇区号为:MBR_LBA=0x00000000处是主引导记录,等同位于硬盘的0磁道0柱面1扇区。
在总共 512 字节的主引导扇区中,MBR 只占用了其中的 446 个字节(ofs:0 - ofs:1BDH),另外的 64个字节(ofs:1BEH - ofs:1FDH)交给了 DPT(Disk Partition Table 盘分区表),最后两个字节“55 AA”(ofs:1FEH - ofs:1FFH)是分区的结束标志。 MBR定义如下:
- typedef struct
- {
- uchar bootcode[446]; //ofs:0.启动代码。“FA 33 C0 8E D0 BC…”.
- PartitionTable PT[4]; //ofs:446.分区表 length=4*16.
- uint EndingFlag; //ofs:510.结束标识:0xAA55.
- }MBR_tag;
Bootcode[446]启动代码一般是固定的,用于引导 x86,不用管。
分区表项的定义如下:
- typedef struct
- {
- uchar BootFlag; //启动标志
- CHS StartCHS; //分区开始的柱面、磁头、扇区
- uchar SystemID; //分区类型
- CHS EndCHS; //分区结束的柱面、磁头、扇区
- ulong RelativeSectors; //分区起始扇区数,指分区相对于记录该分区的分区表的扇区位置之差 (该分区表:LBA=0x0)。
- ulong TotalSectors;//分区总扇区数
- }PartitionTable;
其中 CHS为一个柱面、磁头、扇区的结构,定义如下:
- struct CHS
- {
- uchar Head; //磁头。
- unsigned Sector : 6; //扇区。
- unsigned CyH2 : 2; //柱面(高两位)。
- uchar CyL8; //柱面(低八位)。
- ulong Cylinder() {return (uint(CyH2)*256+CyL8);} //返回柱面值
- void SetCylinder(uint Cylinder) //设置柱面值 {
- CyH2=(Cylinder>>8)&0x3; CyL8=(Cylinder&0xff);
- }
- };
例:80 01 01 00 0B FE BF FC 3F 00 00 00 7E 86 BB 00
在这里我们可以看到:
- “80”是一个分区的激活标志,表示系统可引导;
- “01 01 00”表示分区开始的磁头号为 01,开始的扇区号为 01,开始的柱面号为 00;
- “0B”表示分区的系统类型是 FAT32,其他比较常用的有 04(FAT16)、06(bigFAT16)、01(FAT12)、07(NTFS);
- “FE BF FC”表示分区结束的磁头号为 254,分区结束的扇区号为 63、分区结束的柱面号为 764;
- “3F 00 00 00”表示首扇区的相对扇区号为 63;
- “7E 86 BB 00”表示总扇区数为 12289622。
系统引导记录(DBR)
绝对扇区号为:DBR_LBA=MBR.PT[0].RelativeSectors 处是 DBR,等同位于硬盘的 0 磁道 1柱面 1 扇区(512 字节),是操作系统可以直接访问的第一个扇区,它包括一个引导程序和一个被称为 BPB(Bios Parameter Block)的本分区参数记录表。引导程序的主要任务是当 MBR将系统控制权交给它时,判断本分区跟目录前两个文件是不是操作系统的引导文件(以 DOS为例,即是 Io.sys和 Msdos.sys)。如果确定存在,就把其读入内存,并把控制权交给该文件。BPB参数块记录着本分区的起始扇区、结束扇区、文件存储格式、硬盘介质描述符、根目录大小、FAT个数,分配单元的大小等重要参数。 DBR定义如下:
- typedef struct
- {
- uchar bJmpBoot[3]; //ofs:0.典型的如:0xEB,0x3E,0x90。
- char bOEMName[8]; //ofs:3.典型的如:“MSWIN4.1”。
- uint BPB_wBytesPerSec; //ofs:11.每扇区字节数。
- uchar BPB_bSecPerClus; //ofs:13.每簇扇区数。
- uint BPB_wReservedSec; //ofs:14.保留扇区数,从 DBR到 FAT的扇区数。
- uchar BPB_bNumFATs; //ofs:16.FAT的个数。
- uint BPB_wRootEntry; //ofs:17.根目录项数。
- uint BPB_wTotalSec; //ofs:19.分区总扇区数(<32M时用)。
- uchar BPB_bMedia; //ofs:21.分区介质标识,优盘一般用 0xF8。
- uint BPB_wSecPerFAT; //ofs:22.每个 FAT占的扇区数。
- uint BPB_wSecPerTrk; //ofs:24.每道扇区数。
- uint BPB_wHeads; //ofs:26.磁头数。
- ulong BPB_dHiddSec; //ofs:28.隐藏扇区数,从 MBR到 DBR的扇区数。
- ulong BPB_dBigTotalSec; //ofs:32.分区总扇区数(>=32M时用)。
- uchar bDrvNum; //ofs:36.软盘使用 0x00,硬盘使用 0x80。
- uchar bReserved1; //ofs:37.保留。
- uchar bBootSig; //ofs:38.扩展引导标记:0x29。
- uchar bVolID[4]; //ofs:39.盘序列号。
- char bVolLab[11]; //ofs:43.“Msdos ”。
- char FileSysType[8]; //ofs:54.“FAT16 ”。
- uchar ExecutableCode[448]; //ofs:62.引导代码。
- uint EndingFlag; //ofs:510.结束标识:0xAA55。
- }DBR_tag;