2. BIOS 与 UEFI 对比:传统 BIOS 的 MBR 分区表与启动流程,UEFI 的 GPT 分区表与安全启动 (Secure Boot) 机制
在 x86 架构的计算机中,固件接口是硬件与操作系统内核之间的第一层桥梁。传统 BIOS(Basic Input/Output System)与现代 UEFI(Unified Extensible Firmware Interface)在分区表格式、启动流程、安全机制上存在本质差异。理解这些差异是分析 Linux 内核启动入口的关键前提。
2.1 传统 BIOS + MBR 启动流程
BIOS 启动流程遵循“固定地址、链式加载”的模型,其核心依赖主引导记录(MBR)中的 512 字节引导代码。
2.1.1 MBR 分区表结构
MBR 位于磁盘的第一个扇区(LBA 0),其布局如下:
| 偏移地址 | 大小 | 内容 |
|---|---|---|
| 0x0000 | 446 字节 | 第一阶段引导代码(Boot Code) |
| 0x01BE | 16 字节 | 第 1 个分区表项 |
| 0x01CE | 16 字节 | 第 2 个分区表项 |
| 0x01DE | 16 字节 | 第 3 个分区表项 |
| 0x01EE | 16 字节 | 第 4 个分区表项 |
| 0x01FE | 2 字节 | 魔数 0x55AA(启动签名) |
关键限制:MBR 使用 32 位逻辑块地址(LBA),最大支持 2 TiB 磁盘容量。每个分区表项仅 16 字节,无法存储校验和或备份表。
2.1.2 BIOS 启动步骤
- 上电自检(POST): 初始化硬件,检测内存、CPU、芯片组。
- 启动设备枚举: 按 CMOS 中设置的启动顺序扫描磁盘。
- 加载 MBR: 将磁盘第一个扇区(512 字节)加载到内存地址
0x7C00。 - 校验签名: 检查最后两个字节是否为
0x55AA。 - 跳转执行: CPU 跳转到
0x7C00执行 MBR 中的引导代码。 - 链式加载: MBR 代码读取活动分区的卷引导记录(VBR),VBR 再加载引导管理器(如 GRUB Stage 1.5 / Stage 2)。
实模式限制: BIOS 启动全程运行在 16 位实模式,CPU 只能访问 1 MiB 地址空间。GRUB 等引导加载器必须通过 A20 地址线开启和切换到保护模式,才能加载 Linux 内核。
2.2 UEFI + GPT 启动流程
UEFI 取代了传统 BIOS 的固化中断服务,提供一套标准化的运行时服务与启动服务。GPT(GUID Partition Table)是 UEFI 规范强制要求的分区表格式。
2.2.1 GPT 分区表结构
GPT 使用 64 位 LBA,支持超过 2 TiB 的磁盘。其布局包含保护性 MBR、主 GPT 头、分区表项数组、以及备份 GPT 头。
| LBA 位置 | 内容 | 说明 |
|---|---|---|
| LBA 0 | 保护性 MBR | 防止旧版工具误识别为未分区磁盘 |
| LBA 1 | 主 GPT 头 | 包含分区表起始 LBA、分区项数量、CRC32 校验 |
| LBA 2 ~ 33 | 分区表项数组 | 每个分区项 128 字节,支持 128 个分区 |
| LBA -33 ~ -1 | 备份分区表项 + 备份 GPT 头 | 磁盘末尾冗余备份,增强容错 |
关键优势:GPT 使用 64 位 LBA,最大支持 8 ZiB 磁盘容量。每个分区拥有全局唯一标识符(GUID)和分区名称(最长 36 字符),并存储 CRC32 校验和以检测数据损坏。
2.2.2 UEFI 启动步骤
- 安全初始化: UEFI 固件初始化 CPU、芯片组、内存控制器,进入 64 位平坦模式。
- 扫描 EFI 系统分区(ESP): 固件读取 GPT 分区表,定位 FAT32 格式的 ESP 分区。
- 读取启动管理器: 固件从
EFI\BOOT\BOOTX64.EFI(x86_64 架构)加载 UEFI 应用程序。 - 安全启动校验(若启用): 固件验证引导加载器数字签名是否在数据库(DB)中。
- 执行引导加载器: 引导加载器(如 GRUB、systemd-boot)读取配置文件,加载 Linux 内核。
- 退出启动服务: 引导加载器调用
ExitBootServices(),将控制权移交给内核。
UEFI 运行时服务: 即使在操作系统接管后,UEFI 仍保留一组运行时服务(如
GetVariable、SetVariable、GetTime),内核可通过 EFI 系统表调用这些服务。
2.3 安全启动 (Secure Boot) 机制
安全启动是 UEFI 规范 2.3.1 引入的可选功能,旨在防止未经签名的恶意代码在固件与操作系统之间执行。其核心基于公钥基础设施(PKI)和签名数据库。
2.3.1 安全启动数据库架构
| 数据库 | 存储内容 | 作用 |
|---|---|---|
| PK (Platform Key) | 平台公钥 | 建立固件与平台所有者之间的信任根 |
| KEK (Key Exchange Key) | 操作系统公钥 | 授权更新 DB/DBX 的签名密钥 |
| DB (Signature Database) | 允许执行的签名/哈希 | 白名单:允许加载的引导加载器与内核 |
| DBX (Forbidden Signatures) | 禁止执行的签名/哈希 | 黑名单:阻止已知恶意或已撤销的引导组件 |
2.3.2 安全启动验证流程
- 固件加载引导加载器: UEFI 固件读取
BOOTX64.EFI文件。 - 提取数字签名: 固件解析 PE/COFF 格式的签名证书或哈希值。
- 查询 DB 数据库: 将签名与 DB 中的白名单条目比对。
- 查询 DBX 数据库: 检查签名是否在撤销黑名单中。
- 执行或拒绝: 若签名匹配 DB 且不在 DBX 中,则允许执行;否则拒绝启动。
- 链式信任传递: 引导加载器(如 shim → GRUB → Linux 内核)逐级验证下一阶段组件的签名。
Linux 兼容性挑战: 由于 Linux 内核签名密钥通常不在固件 DB 中,主流发行版使用
shim(由 Microsoft 签名的第一级引导加载器)作为桥梁。shim 验证 GRUB 签名,GRUB 再验证内核签名。若内核未签名,需在固件设置中禁用安全启动。
2.4 BIOS 与 UEFI 核心对比
| 对比维度 | 传统 BIOS | UEFI |
|---|---|---|
| 处理器模式 | 16 位实模式 | 32/64 位平坦模式 |
| 分区表 | MBR(32 位 LBA,≤ 2 TiB) | GPT(64 位 LBA,≤ 8 ZiB) |
| 引导代码位置 | MBR 扇区(0x7C00) | ESP 分区中的 .EFI 文件 |
| 可扩展性 | 差,依赖中断向量表 | 强,支持驱动协议与运行时服务 |
| 安全机制 | 无内置签名验证 | 安全启动(PK/KEK/DB/DBX) |
| 用户界面 | 文本菜单,键盘导航 | 图形界面,支持鼠标与网络 |
| 启动速度 | 较慢,串行初始化 | 较快,并行初始化 |
内核启动入口差异: BIOS 下 Linux 内核从实模式入口
startup_32(arch/x86/boot/header.S)开始,需自行切换保护模式与长模式。UEFI 下内核通过 EFI 桩代码(efi_stub_entry)直接进入 64 位模式,并利用 UEFI 提供的内存映射表与系统表。