viploser 发表于 2021-2-8 10:24:18

关于MBR和GPT的基础知识及编码解读并系统引导详解

[ 本帖最后由 viploser 于 2021-2-8 11:17 编辑 ]\n\n

零 前言

首先我们需要明确一个概念,我们日常表述MBR和GPT都是容易引起混淆的非规范性表达。
MBR——主引导记录;用于将启动指令从BIOS传递给操作系统的简短编码,包括启动引导程序GRUB/bootloader、磁盘分区表DPT、结束标志;位于磁盘第一个扇区、即前512个字节的位置。
MBR分区表——采用MBR模式标示磁盘分区结构的分区表;包括MBR中的DPT、主分区/扩展分区的DBR、逻辑分区的EBR,三者共同构成的链式结构;主要特征是最多支持4个主分区、最大支持2TB磁盘
GUID分区表——在Intel的EFI标准发布之后,为了更灵活地控制磁盘分区并适应更大的硬盘,而产生的一种磁盘分区结构标示标准;其最主要特征是用全局唯一标识符(GUID)编码每个分区,因此称为GUID分区表;其主要优势为支持大硬盘、自带备份、针对关键数据结构存在循环冗余检验值。GUID分区表是UEFI标准的一部分。
GPT——GUID分区表简称gpt分区表,使用GUID分区表标示结构的磁盘称为GPT磁盘。

同时补充两个概念:EFI和UEFI。可以将二者均理解为协议,且UEFI是EFI的继承和扩展。
EFI——可扩展固件接口,由Intel在2002年发布,可以理解为操作系统和硬件之间的指令交换中台,其开发目的是替代Legacy BIOS。
UEFI——统一可扩展固件接口,在2005年Intel将EFI交由UEFI论坛推广发展,后者增加和改进了加密编码、网络认证、用户接口架构。


一 MBR分区表

主引导记录MBR
前446个字节——启动引导程序GRUB/bootloader,这一部分内容和操作系统有关系,因操作系统而已。是从硬件启动到操作系统运行的桥梁。简单说就是告诉电脑,去哪个位置找哪个文件(把这个文件执行起来就可以进一步加载操作系统了、可以理解为降落伞的引伞)。
之后的64个字节——分区表DPT,包括四个主分区/扩展分区的分区标示。每个主/扩展分区标示占用16个字节。
      位置————————————字段———————————解读注释
      第1字节——————————-引导标志————————--(08)16代表活动分区,即Windows的可引导分区;(00)16代表非活动分区。
      第2字节——————————-起始磁头号
      第3字节低6位———————-起始扇区号
      第3字节高2位&第4字节——--起始柱面号
      第5字节——————————-分区类型—————————(05)16/(0F)16代表扩展分区;(0B)16代表FAT32;(07)16代表NTFS分区。
      第6字节——————————-结束磁头号
      第7字节低6位———————-结束扇区号
      第7字节高2位&第8字节——--结束柱面号
      第9~12字节————————-分区前已占用扇区数———解读时按照逆序排列(字节内8不取反)后再转换为十进制即为分区前已占用扇区数。
      第13~16字节———————--本分区的总扇区数————解读时按照逆序排列(字节内8不取反)后再转换为十进制即为本分区总扇区数。
我们举例说明:例如使用DiskGenius或者WinHex读取到DPT前16个字节为80 01 01 00 07 FE FF FF 3F 00 00 00 82 C1 3B 3A,首先应断句为(80)(01 01 00)(07)(FE FF FF)(3F 00 00 00)(82 C1 3B 3A)。
      80——此分区为活动分区,系统将在此硬盘启动。
      01 01 00——此分区的起始位置为0柱面,1磁头,1扇区。
      07——此分区文件系统类型为NTFS
      FE FF FF——此分区结束位置为1023柱面,254磁头,63扇区。(磁头号FE=254,扇区号(11 1111)2=(63)10,柱面号=(11 11111111)2=(1023)10)
      3F 00 00 00——分区前有63个扇区。(3F 00 00 00逆序为00 00 00 3F=(63)10)
      82 C1 3B 3A——此分区共976994690个扇区(82 C1 3B 3A逆序为3A 3B C1 82=(976994690)10)。
此分区大小约为465.87GB(每个扇区512字节,976994690*512/1024/1024/1024)。
/*有没有发现一个问题。在这种编码模式下DPT的2~4和6~8字节处最大值就是(FE FF FF),也就是1023柱面的结束位置。所以才有了后面8个字节的扇区数量标示,用来指示1024柱面后面的分区。*/
/*这又引申出一个问题(BIOS的1024柱面问题):在DPT的2~4和6~8字节处、MBR使用3个字节来表示磁盘地址,其中10位表示柱面、6位表示头、8位表示扇区;如果一个扇区512字节,那么能表示的磁盘地址为2^10×2^6×2^8×512Bytes=8.4GB;又因为Legacy BIOS的开机过程涉及PBR→NTLDR/Bootmgr的过程(后文详述);因此,启动引导程序只能放在分区的前8.4GB位置。*/
四个主/扩展分区的分区表均为上述编码规则。
最后的两个字节——固定为十六进制的55和AA,表示MBR结束。

分区引导扇区PBR
根据DPT可以寻址到每一个分区的起始位置,每个分区起始的第一个扇区(分区的前512字节)。PBR的结构与文件系统类型有关,NTFS与FAT32的PBR格式不同。
对于FAT32文件系统,DBR编码方式如下。
      长度——-字段————————解读注释
      3————转跳指令
      8————OEMID
      2————每扇区字节数——----一般为512
      1————每簇字节数
      2————保留扇区数
      1————FAT个数
      2————根目录项数————-FAT32必须为(00 00)16
      2————小扇区数————----FAT32必须为(00 00)16
      1————储介质——————--硬盘为F8;3.5英寸软盘为F0
      2————每个FAT扇区数——--FAT32必须为(00 00)16;此项目仅对FAT12/16有效
      2————每道扇区数————-描述磁盘物理结构
      2————磁头数
      4————多硬盘相关————-该块硬盘前用于存放引导代码及分区表的扇区总数
      4————总扇区数
      4————每个FAT扇区数——--此项目仅对FAT32有效
      2————活动FAT数—————0~3位表示活动FAT数;7位表示运行时FAT映射到所有FAT;4~6位保留
      2————文件系统版本———-高字节表示主要修订号;低字节表示次要修订号
      4————根目录簇号————-一般为2
      2————文件系统扇区号——-一般为1
      2————备份引导扇区号——-FAT32一般为6
      12———-保留扇区
      1————物理驱动器号———-物理硬盘为(80)16;软盘驱动器为(00)16
      1————保留字节
      1————WinNT识别扇区——-一般为(28)16或(29)16
      4————卷序列号—————--高级格式化时随机取得
      11———-卷表示
      8————系统ID——————--根据格式化的格式为FAT32/16等
      420——--引导区代码
      2————结束标志—————--固定为(55 AA)16
对于NTFS文件系统,DBR编码方式如下。
      长度——-字段————————————解读注释
      3————跳转指令
      8————OEM代号
      2————每扇区字节数
      1————每簇扇区数
      2————保留字节
      3————个(00)16字节
      2————2个未用字节
      1————媒体类型
      2————2个未用字节
      2————每磁道扇区数
      2————磁头数
      4————隐藏扇区数
      4————4个未用字节
      4————固定字节——————————NTFS总为(80 00 80 00)16
      8————扇区总数
      8————$MFT的起始簇号
      8————$MFTMirr的起始簇号
      1————文件记录的大小描述
      3————3个未用字节
      1————索引缓冲的大小描述
      3————3个未用字节
      8————卷序列号——————————高级格式化时随机取得
      4————校验和
      426——--引导区程序
      2————结束标志——————————固定为(55 AA)16

扩展引导记录EBR
MBR的DPT中允许存在一个扩展分区(DPT该分区标识第5字节为(05)16/(0F)16);对该分区寻址后,该分区的DBR位置是一个扩展引导记录EBR;其结构与MBR类似,同样是446+16*4+2的512字节(一个扇区)的长度;但编码方式不同。
      长度-字段———————————-解读注释
      446--留空———————————-强制为(00)16
      16—-此分区寻址参数——————此字段内第9~12字节处的地址为相对偏移
      16—-下一个EBR寻址位置————如果为(00)16则表示当前分区为最后一个逻辑分区
      32—-留空———————————-强制为(00)16
      2——结束标志—————————-固定为(55 AA)16
/*我非常不想引入扇区偏移这个定义,扇区的概念是能放数据的区域,因此使用这个概念容易在分析时陷入前一个分区最后一个扇区和后一个分区第一个扇区相互叠压的逻辑陷阱。*/
/*磁盘就是排好的一大堆格子,就是一个数轴,分区前占用扇区的数量就是用掉的格子数,这个数字就是最后占用了的格子后方的刻度线,也是此分区就开始占用格子时左侧的起始刻度线。并不发生重叠问题。扇区不是放在刻度线上的围棋。*/
用实际数字来演练一下。已知MBR最后一个分区的DPT标示为00 FE FF FF 0F FE FF FF 00 F0 FF 0A 00 08 40 00,根据此DPT寻址EMR第一个分区的DPT表示为00 FE FF FF 07 FE FF FF 00 08 00 00 00 90 21 00,那么这个逻辑分区物理地址在哪里?MBR的DPT的第5字节为(0F)16,表示为扩展分区;第2~4和6~8字节均为最大值(FE FF FF)16,则采用实际占用来计算;扩展分区物理地址为00 F0 FF 0A,及0x0AFFF000处,这个值存下备用。看EMR里的逻辑分区,这里的00 08 00 00是逻辑地址,是对00 F0 FF 0A的相对偏移,偏移量为0x00000800。则这个逻辑分区的物理地址为0x0AFFF000+0x00000800=0x0AFFF800。

以上就是MBR分区表的字段位置和编码解析,同时示范了寻址过程。


二 GPT分区表

相对于MBR分区表,GPT分区表寻址较为简单,同时也预留了大量可以进一步标示的空编码位。我们需要引入一个概念,LBA,逻辑区块地址,GPT分区表将整个磁盘划分为若干个大小为512字节的区域,进行统一管理。这个区域的大小和MBR分区表中的扇区相同(在默认设置、不去魔改的前提下),但是扇区没有0扇区的说法、但LBA的编码从0开始(LBA0~LBA若干),因此为了区分,我使用LBA进行表述。/*我原来也不明白为什么要引入LBA0,后来看完了GUID文档才体会到这其中的妙处。*/
LBA0——完整的MBR结构,但是数据不同,称为Protected MBR。
LBA1——真正的GPT表头,包含了分区表本身的位置与大小、记录了备份GPT分区(最后34个LBA)的位置、放置了分区表的校验码(CRC32)。具体编码如下。
      长度—-字段————————————解读注释
      8———签名————————————"EFI PART",(45 46 49 20 50 41 52 54)16
      4———修订版本号————————-例如1.0版本为(00 00 01 00)16
      4———分区表头的大小——————-一般是92字节,(5C 00 00 00)16;逆序排列字节(字节内不取反)后转十进制解读
      4———CRC32校验—————————计算前填充(00 00 00 00)16;计算出所有分区表项的CRC32校验后再计算这个CRC32
      4———保留————————————-必须是(00 00 00 00)16
      8———当前LBA——————————-这个分区表头的扇区位置;逆序排列字节(字节内不取反)后转十进制解读
      8———备份LBA——————————-另一个分区表头LBA-1的扇区位置;逆序排列字节(字节内不取反)后转十进制解读
      8———第一个可用于分区的LBA——--主分区表最后一个LBA+1的扇区位置;逆序排列字节(字节内不取反)后转十进制解读
      8———最后一个可用于分区的LBA—--备份分区表第一个LBA-1的扇区位置;逆序排列字节(字节内不取反)后转十进制解读
      16——-硬盘GUID—————————--在类UNIX系统中也叫UUID
      8———分区表项的起始LBA—————-LBA2的位置(扇区位置)
      4———分区表项的数量———————Windows下一般是(80 00 00 00)16;逆序排列字节(字节内不取反)后转十进制解读
      4———一个分区表项的大小—————一般是(80 00 00 00)16;逆序排列字节(字节内不取反)后转十进制解读
      4———分区阵列CRC32校验—————所有分区表项的检验和,一般是(00 00 40 00)16
      420——保留————————————-必须是(00 00 01 00)16
LBA2~LBA33——分区参数的记录位置(类似于MBR的DPT),32LBAx512Bytes=16KB=128Bytesx128partions;这部分可以看成一个16KB的整体区域,GPT分区表中每个分区参数占128字节的空间,可以存储128个分区参数。具体编码如下
      长度——-字段—————————-—解读注释
      16———-分区类型GUID—————-例如EFI分区为C12A7328-F81F-11D2-BA4B-00A0C93EC93B
      16———-分区GUID
      8————起始LBA(小端序)———小端序:低位字节存入低地址,高位字节存入高地址。
      8————末尾LBA
      8————属性标签
      72———-分区名—————————-可以包括36个UTF-16小端序字符;不同于卷标
LBA-1~LBA-34(倒数第1~34个LBA)——在磁盘末尾备份LBA1~LBA34的数据,是GPT分区表的容错备份。

关于LBA0的妙处
GPT分区表在LBA0做了一个Protected MBR,对于不识别GPT分区表的设备来说,能读取一个完整构架的MBR出来。但是这个“MBR”的GRUB/bootloader无法担当硬件启动到操作系统运行的桥梁,同时“DPT”的第一个分区第5字节的分区类型是无法识别的(EE)16;在二者共同作用下,BIOS实际只完成了对Protected MBR的读取,之后因为无法识别就停止了对硬盘数据的访问;这样一来即使把GPT磁盘接入不兼容/不支持的设备,也不会造成硬盘分区表损坏甚至是硬盘内数据的丢失。其实就相当于一个防呆设计,只不过是防电脑的呆。

以上就是GPT分区表的字段位置和编码解析,寻址过程为逆序重新排列字节(字节内8位二进制不取反)后再转换为十进制解读,不再重复举例示范。


三 苹果公司的混合分区表

GPT的LBA0就是一个MBR,只不过是空白的Protect MBR而已(纯UEFI模式这个“MBR”只有451字节处的0xEE和511~512字节处的0x55AA,其余均是0x00)。既然是“MBR”,我们在这个 Protect MBR上写入GRUB/bootloader和DPT会怎么样?这就是苹果搞出来的混合分区表。
      基本矛盾是——Mac OS X是完全EFI/UEFI引导的,而且苹果的系统构架并不需要PBR(Mac OS X的引导过程是直接从启动分区里找到引导程序加载系统内核);而WindowsXP是纯纯的MBR引导。
      比较幸运的是——EFI/UEFI是一款足够强大的平台,EFI/UEFI是c语言写的,可以模块化的增加功能,而且UEFI网络和用户接口的加入使本来就技术激进苹果拥有了足够强大的底层支持(如果你用过苹果电脑的联网恢复功能,就知道苹果的UEFI有多么强大,在主硬盘被低格的情况下可以通过UEFI联网恢复系统)。
      苹果的操作是——苹果开发了Boot Camp,这个东西实际就干了4件事:修改分区参数(给WinXP腾出一块磁盘空间),让Protect MBR称为真的MBR(把XP的启动引导程序放进GRUB、把GPT前四个分区拷贝DPT),激活NVRAM里的隐藏参数,准备整套的独家驱动。
      BC魔改之后的Mac OS X的引导流程是——开机→初始化→加载→UEFI→苹果自己的EFI系统→加载NVRAM参数→引导程序→系统内核→Mac OS X。
      BC魔改之后的WindowsXP的引导流程——开机→初始化→加载→UEFI→苹果自己的EFI系统→加载NVRAM参数→Boot Camp→MBR→DPT→PBR→NTLDR→boot.ini→winload.exe→系统内核加载→WindowsXP。


四 Legacy BIOS启动及引导过程

按下开机电源→主板供电(电压不稳)→主板芯片向CPU发送并保持RESET复位信号→CPU初始化→电压稳定→主板芯片撤去RESET信号→CPU执行转跳指令至BIOS启动代码→BIOS加电自检(POST)→关键硬件自检→执行显卡BIOS启动代码→调用显卡BIOS初始化代码→显卡初始化→主BIOS调用其他BIOS启动代码及初始化代码完成各硬件初始化→检查CPU类型及工作频率并显示输出→检查内存并显示输出→硬盘/光驱/串口/并口检测并显示输出→运行即插即用代码检测即插即用设备并显示输出→列显系统配置BIOS中断及I/O调制→读取CMOS中ESCD→MBR→GRUB/bootloader&DPT→PBR→*→NTLDR→boot.ini→winload.exe→系统内核加载→Windows XP(*→BootMg→BCD→bootmgfw.efi→内核加载→Windows Vista/7)


五 UEFI启动及引导过程(只讨论非苹果电脑的UEFI)

在PC机的UEFI模式下,主硬盘第一分区为ESP(Windows命名法)或EFI(Linux命名法)区。这个分区本质上是一个FAT16分区打上了特殊的分区类型标签。分区内只有一个EFI文件夹,EFI内有Boot文件夹(和UEFI接口接驳)和不同操作系统的文件夹(与各系统内核加载器接驳);Boot文件夹和系统引导文件夹依赖efi文件之间类似“指针”的之乡关系建立连接。

对于单纯的UEFI+GPT的Windows单系统,引导过程有两种:Windows Boot Manager方案和硬盘引导方案。
Windows Boot Manager方案:UEFI程序→NVRAM→GPT→LBA1→ESP分区→EFI/Microsoft/Boot/bootmgfw.efi→EFI/Microsoft/Boot/BCD→C:\Windows\system32\winload.efi→Windows内核→Windows系统
硬盘引导方案:UEFI程序→NVRAM→GPT→LBA1→ESP分区→EFI/Boot/bootx64.efi→EFI/Microsoft/Boot/BCD→C:\Windows\system32\winload.efi→Windows内核→Windows系统

而如果是基于UEFI的多系统联合引导(比如我在Dell OptiPlex 9020M上装了Win10+Hacintosh10.15.3+Ubuntu20.04.2),我的EFI文件目录如下。
      EFI
      |——Boot
      |      |——bootx64.efi~硬盘引导根入口;直接指向EFI/Clover/CLOVERX64.efi;在UEFI菜单中显示
      |      |——fbx64.efi~Ubuntu安装过程生产的FallBackX64引导;在经EFI/ubuntu/grubx64.efi引导时可以调用进行引导修复
      |      └——mmx64.efi~Ubuntu的引导根入口;和EFI/ubuntu/grubx64.efi是同一个文件;在UEFI菜单中显示
      |——Microsoft
      |      |——Boot
      |      |      |——BCD~指向Windows的内核加载程序
      |      |      |——boot.stl
      |      |      |——bootmgfw.efi~Windows Boot Manager引导入口;在UEFI菜单中显示
      |      |      |——bootmgr.efi
      |      |      |——BOOTRSTAT.DAT
      |      |      |——memtest.efi
      |      |      |——winsipolicy.p7b
      |      |      |——zh-CN~对应语言的引导备份和应急引导
      |      |      |                |——bootmgfw.efi.mui~在系统迭代过程中代替EFI/Microsoft/Boot/bootmgfw.efi作用
      |      |      |                |——bootmgr.efi.mui
      |      |      |                └——memtest.efi.mui
      |      |      |——kdstub.dll~这一系列dll文件是CLOVERX64.efi接管Windows引导后的配置和依赖文件
      |      |      |——kdnet_uart16550.dll
      |      |      |——kd_0C_8086.dll
      |      |      |——kd_02_1af4.dll
      |      |      |——kd_xx_xxxx.dll
      |      |      └——kd....dll~EFI/Clover/CLOVERX64.efi→dll→EFI/Microsoft/Boot/BCD→C:\Windows\system32\winload.efi
      |      └——Recovery
      |                └——BCD~Windows Recovery Environment引导入口;在高级重启时EFI/Microsoft/Boot/BCD经此文件指向RE分区的WinRE.img
      |——ubnuntu
      |      |——grubx64.efi~Ubuntu的引导入口;和EFI/Boot/mmbx64.efi是同一个文件;EFI/Clover/CLOVERX64.efi可指向此处
      |      └——grub.cfg
      └——Clover
                |——CLOVERX64.efi~引导核心~调用config.plist引导Hacintosh;可经EFI/Microsoft/Boot/BCD引导Win,经EFI/ubuntu/grubx64.efi引导Ubuntu
                |——config.plist~黑苹果的核心配置
                |——drivers
                |      └——UEFI~引导黑苹果的系统组件;向Hacintosh返回和苹果电脑相同/相近的基础参数
                |                |——XXX.efi
                |                └——....efi~可以相当于Legacy BIOS调用MBR之前反馈给BIOS的初始化和自检结果
                |——kexts~黑苹果驱动;最难配置的是Intel AX200NGW的网卡
                |      └——Other
                |                |——XXX.kext
                |                └——....kext
                |——themes~Clover的主题;默认是黑底白字键盘操作;可以玩出花来;但是对ESP大小有要求
                └——tools~引导黑苹果的重要组件;也是系统内核的一部分
                        |——bdmesg.efi
                        |——Shell32.efi
                        |——Shell64.efi
                        └——Shell64U.efi
我这套东西默认引导是:UEFI程序→NVRAM→GPT→LBA1→ESP分区→EFI/Boot/bootx64.efi→EFI/Clover/CLOVERX64.efi,在此处中断等待选择操作系统。
选择Windows则bootx64.efi→EFI/Microsoft/Boot/....dll→EFI/Microsoft/Boot/BCD→C:\Windows\system32\winload.efi→Windows内核→Windows
选择Hacintosh则bootx64.efi→EFI/Clover/CLOVERX64.efi→config.plist→EFI/Clover/drivers/UEFI/....efi→/System/Library/CoreServices/boot.efi→/System/Library/Kernels/kernel→Hacintosh
选择Ubuntu则bootx64.efi→EFI/Clover/CLOVERX64.efi→EFI/ubuntu/grubx64.efi→grub→ubuntu内核(可选)→initrd→initramfs→init script→/sbin/init→runlevels& /etc/rc?.d
比较神奇的是EFI/ubuntu/grubx64.efi→grub之后还可以跳转到EFI/Boot/bootx64.efi和EFI/Boot/mmbx64.efi。

以上我综合描述了一台三系统设备的引导路径。


六 参考文献

https://blog.csdn.net/zt_xcyk/article/details/53669383
https://blog.csdn.net/Hilavergil/article/details/79270379
https://github.com/Hilaver/NtfsResolution/
https://blog.csdn.net/li33293884/article/details/50562527
https://blog.51cto.com/groot/1842985
https://www.cnblogs.com/zerxoi/p/13228039.html
https://blog.csdn.net/diaoxuesong/article/details/9406015
https://blog.csdn.net/haiross/article/details/38659825
https://blog.csdn.net/Casuall/article/details/98481469
https://www.feng.com/post/6890655
https://blog.csdn.net/housecarl/article/details/89329860
https://www.cnblogs.com/LittleHann/p/6974928.html
https://blog.csdn.net/yeshahayes/article/details/52806095
https://blog.csdn.net/akimotomei/article/details/105102041
https://blog.csdn.net/qq_39431829/article/details/97310556
https://justinyan.me/post/3993
https://blog.csdn.net/liveinjs/article/details/16996801
https://blog.csdn.net/liveinjs/article/details/17002663


以上就是本次《关于MBR和GPT的基础知识及编码解读并系统引导详解》的全部内容。



viploser
https://arcice.org
UTC+8.00 2021-02-08 10:24

新空气 发表于 2021-2-8 16:22:57

收藏

ZhanBE 发表于 2021-2-9 08:10:16

太硬核了,直呼过瘾
页: [1]
查看完整版本: 关于MBR和GPT的基础知识及编码解读并系统引导详解