2. BIOS 与 UEFI 固件:BIOS 与 UEFI 的区别、启动顺序、硬件自检(POST)过程
在 x86 架构的计算机中,固件(Firmware)是硬件与操作系统之间的第一层软件接口。它负责在 CPU 上电后完成最基本的硬件初始化,并最终将控制权交给引导加载程序(Bootloader)。本章深入剖析传统 BIOS 与现代 UEFI 固件的核心差异、启动顺序以及硬件自检(POST)的详细流程。
2.1 传统 BIOS 固件详解
BIOS(Basic Input/Output System)自 1980 年代起成为 IBM PC 兼容机的标准固件。它存储在主板上的 ROM(只读存储器)中,是 16 位实模式下的软件。
2.1.1 BIOS 的启动顺序
BIOS 的启动流程遵循一个严格的线性顺序,其核心步骤如下:
- 上电复位(Power-on Reset):CPU 的 CS:IP 寄存器被硬件强制初始化为 0xF000:0xFFF0,指向 BIOS ROM 的入口地址。
- 硬件自检(POST):BIOS 执行一系列诊断测试,验证 CPU、内存、芯片组、显卡、键盘等关键组件是否正常。
- 初始化硬件:BIOS 调用各硬件设备(如中断控制器、定时器、DMA 控制器)的初始化代码。
- 查找引导设备:BIOS 根据用户配置的启动顺序(如:USB → 硬盘 → CD-ROM),依次读取每个设备的第一个扇区(MBR,主引导记录)。
- 加载并执行 MBR:BIOS 将 MBR(512 字节)加载到内存地址 0x7C00,并跳转执行。MBR 中的代码随后加载活动分区的 VBR(卷引导记录),最终启动操作系统。
2.1.2 BIOS 硬件自检(POST)流程
POST 是 BIOS 启动过程中最关键的诊断阶段。它通过一系列测试确保系统基本功能正常。如果检测到致命错误,BIOS 会通过蜂鸣声代码(Beep Codes)或屏幕上的错误代码报告问题。
| POST 阶段 | 测试内容 | 失败表现 |
|---|---|---|
| CPU 测试 | 验证 CPU 寄存器、标志位、内部缓存 | 系统无响应,无蜂鸣声 |
| ROM BIOS 校验和 | 检查 BIOS 代码完整性 | 连续短蜂鸣声 |
| DMA 与定时器 | 初始化 DMA 控制器和系统定时器 | 系统死机 |
| 基本内存测试 | 测试第一个 64KB 内存(实模式关键区域) | 一长两短蜂鸣声 |
| 显卡初始化 | 检测显卡 BIOS,初始化显示模式 | 屏幕无显示,一长三短蜂鸣声 |
| 完整内存测试 | 测试全部可用 RAM | 内存错误代码显示 |
| 键盘控制器 | 检测键盘是否存在,初始化键盘接口 | 键盘灯不亮,系统暂停 |
| 存储设备枚举 | 检测 IDE/SATA 设备,分配中断 | 启动设备未找到错误 |
2.2 现代 UEFI 固件详解
UEFI(统一可扩展固件接口)是 BIOS 的现代替代方案。它提供了一个标准化的、与操作系统无关的启动环境。UEFI 运行在 32 位或 64 位保护模式/长模式下,拥有独立的驱动模型和文件系统支持。
2.2.1 UEFI 的启动顺序
UEFI 的启动流程比 BIOS 更灵活,它不再依赖 MBR 的 512 字节代码,而是直接加载 EFI 应用程序(.efi 文件)。
- 上电与安全验证(SEC):CPU 上电后,执行 UEFI 安全阶段(SEC),验证固件卷的完整性。
- EFI 前期初始化(PEI):初始化 CPU、芯片组和主内存。此阶段内存尚未完全可用,代码在缓存(Cache-as-RAM)中运行。
- 驱动执行环境(DXE):内存初始化完成后,加载并执行各种 UEFI 驱动程序(如磁盘、网络、显示驱动)。
- 启动设备选择(BDS):UEFI 固件读取 NVRAM 中的启动项(Boot#### 变量),按照优先级尝试启动。
- 加载 EFI 应用程序:UEFI 直接从 ESP(EFI 系统分区)中的 \EFI\BOOT\BOOTX64.EFI(或用户指定的路径)加载引导加载程序(如 GRUB2、systemd-boot)。
- 退出启动服务:引导加载程序调用
ExitBootServices(),接管硬件控制权,UEFI 固件进入后台。
2.2.2 UEFI 硬件自检(POST)流程
UEFI 的 POST 过程与 BIOS 有显著不同。UEFI 将硬件初始化分为多个阶段,并且支持并行初始化,从而加快启动速度。
| UEFI 阶段 | 主要任务 | 与 BIOS 对比 |
|---|---|---|
| SEC(安全阶段) | 验证固件完整性,建立临时内存(Cache-as-RAM) | BIOS 无此阶段,直接跳转到 POST |
| PEI(前期初始化) | 初始化 CPU、芯片组、主内存控制器 | 类似 BIOS 的早期 CPU/芯片组初始化 |
| DXE(驱动执行环境) | 加载 UEFI 驱动,初始化所有总线(PCIe、USB、SATA) | BIOS 在此阶段仅做简单设备枚举 |
| BDS(启动设备选择) | 读取 NVRAM 启动项,加载 EFI 应用程序 | BIOS 在此阶段扫描 MBR 并加载 |
| TSL(短暂系统加载) | 引导加载程序运行,准备退出 UEFI 服务 | BIOS 无此阶段,直接跳转到 MBR |
| RT(运行时) | UEFI 运行时服务(如变量、时间)在操作系统下可用 | BIOS 在操作系统启动后基本不可用 |
2.3 BIOS 与 UEFI 核心区别对比
下表从多个维度对比了传统 BIOS 与现代 UEFI 固件的关键差异:
| 对比维度 | 传统 BIOS | UEFI |
|---|---|---|
| 运行模式 | 16 位实模式 | 32/64 位保护模式或长模式 |
| 寻址空间 | 1MB(实模式限制) | 4GB(32位)或更大(64位) |
| 磁盘分区表 | MBR(最大 2.2TB,最多 4 个主分区) | GPT(最大 9.4ZB,最多 128 个分区) |
| 启动方式 | 加载 MBR(512 字节) | 加载 EFI 应用程序(.efi 文件) |
| 用户界面 | 文本菜单,键盘操作 | 图形界面,支持鼠标和网络 |
| 驱动模型 | 无标准驱动模型,依赖 Option ROM | 标准 UEFI 驱动模型,支持网络和文件系统 |
| 安全特性 | 无安全启动机制 | 支持 Secure Boot,防止未授权代码运行 |
| 启动速度 | 较慢,串行初始化 | 较快,支持并行初始化 |
| 扩展性 | 受限于 16 位代码和 1MB 空间 | 高度模块化,可加载第三方驱动 |
2.4 BIOS 与 UEFI 启动流程对比图
下图直观展示了 BIOS 与 UEFI 在启动流程上的核心差异:
2.5 实战:查看当前系统的固件类型
在 Linux 系统中,可以通过以下命令快速判断当前系统使用的是 BIOS 还是 UEFI:
# 检查 /sys/firmware/efi 目录是否存在
# 如果存在,则系统以 UEFI 模式启动
ls /sys/firmware/efi
# 或者使用 dmidecode 查看固件信息
sudo dmidecode -t 0 | grep -i "uefi\|bios"
# UEFI 系统输出
/sys/firmware/efi 目录存在
# BIOS 系统输出
ls: cannot access '/sys/firmware/efi': No such file or directory
2.6 总结
BIOS 与 UEFI 是 x86 平台启动流程的基石。BIOS 作为 40 年前的遗留技术,其 16 位实模式、MBR 分区和线性启动流程已无法满足现代硬件需求。UEFI 通过引入 64 位运行环境、GPT 分区表、模块化驱动模型和安全启动机制,显著提升了启动速度、安全性和可扩展性。理解这两种固件的工作方式,对于调试内核启动早期阶段、配置引导加载程序以及优化系统启动性能至关重要。