3. x86/x64 体系结构基础:CPU 模式、内存与 I/O
在 BIOS 开发中,CPU 的三种运行模式——实模式、保护模式与长模式——构成了固件启动与操作系统加载的底层基石。理解这些模式下的内存分段、分页机制以及 I/O 空间模型,是编写可靠固件代码的前提。本章将系统梳理这些核心概念,并辅以结构图与对比表格,帮助你建立清晰的硬件抽象视图。
3.1 CPU 运行模式:实模式、保护模式与长模式
x86/x64 处理器从上电复位到操作系统运行,会经历多种运行模式的切换。每种模式决定了 CPU 的寻址能力、指令集可用性以及内存保护策略。
| 特性 | 实模式 (Real Mode) | 保护模式 (Protected Mode) | 长模式 (Long Mode) |
|---|---|---|---|
| 寻址位数 | 20 位 | 32 位 | 64 位 |
| 最大物理内存 | 1 MB | 4 GB | 16 EB (理论) |
| 段机制 | 段基址:偏移 (CS:IP) | 段选择子 + 描述符表 | 段选择子 + 描述符表 (简化) |
| 分页机制 | 无 | 可选 (CR0.PG=1) | 强制启用 |
| 特权级 | 无 (实为 Ring 0) | Ring 0 ~ Ring 3 | Ring 0 ~ Ring 3 |
| 典型用途 | BIOS POST、Bootloader 早期 | 32 位 OS、UEFI DXE 阶段 | 64 位 OS、UEFI 64-bit |
3.2 内存分段机制
分段是 x86 体系结构最基础的内存管理方式。在实模式和保护模式下,CPU 都使用段寄存器来定位内存地址,但两者的计算方式截然不同。
3.2.1 实模式分段
实模式下,物理地址由段基址左移 4 位加上偏移量得到:物理地址 = (段基址 << 4) + 偏移量。段基址存储在 CS、DS、ES、SS 等段寄存器中,偏移量由 IP、BX、SI、DI 等寄存器提供。这种模式只能访问 1 MB 地址空间,且没有保护机制。
3.2.2 保护模式分段
保护模式下,段寄存器不再直接存储基址,而是存储一个指向全局描述符表 (GDT) 或局部描述符表 (LDT) 的段选择子。段选择子包含索引、表指示位 (TI) 和请求特权级 (RPL)。CPU 通过段选择子查找描述符,从中获取段基址、段限长和访问权限,然后进行地址转换与保护检查。
3.3 内存分页机制
分页是保护模式和长模式下实现虚拟内存、进程隔离和按需分页的基础。分页机制将线性地址转换为物理地址,并支持 4 KB、2 MB 和 1 GB 等多种页面大小。
3.3.1 32 位分页 (保护模式)
当 CR0.PG=1 且 CR4.PAE=0 时,启用 32 位分页。线性地址被拆分为页目录索引 (10 位)、页表索引 (10 位) 和页内偏移 (12 位)。CPU 通过 CR3 寄存器指向页目录基址,两级查表完成地址转换。
3.3.2 PAE 分页与长模式分页
物理地址扩展 (PAE) 允许 32 位 CPU 访问超过 4 GB 的物理内存。长模式下强制使用 PAE 风格的分页结构,但线性地址扩展为 48 位 (实际实现) 或 57 位 (5 级分页)。典型 4 级分页结构如下:
- PML4 (Page Map Level 4):CR3 指向 PML4 表,9 位索引。
- PDPT (Page Directory Pointer Table):9 位索引。
- PD (Page Directory):9 位索引。
- PT (Page Table):9 位索引。
- 页内偏移:12 位 (4 KB 页面)。
3.4 I/O 空间与内存映射 I/O
x86 体系结构提供了两种独立的 I/O 访问方式:I/O 端口空间和内存映射 I/O (MMIO)。BIOS 在初始化硬件时,需要根据设备类型选择合适的访问方法。
3.4.1 I/O 端口空间
I/O 端口空间是一个独立的 64 KB 地址空间 (0x0000 ~ 0xFFFF),通过 IN 和 OUT 指令访问。每个端口可以读写 8 位、16 位或 32 位数据。典型设备包括:
- PIC (8259A):端口 0x20/0x21 (主片),0xA0/0xA1 (从片)。
- PIT (8254):端口 0x40 ~ 0x43。
- RTC (CMOS):端口 0x70 (索引),0x71 (数据)。
- 串口 (UART):端口 0x3F8 ~ 0x3FF (COM1)。
3.4.2 内存映射 I/O (MMIO)
MMIO 将设备寄存器映射到物理内存地址空间,CPU 使用普通的 MOV 指令即可访问。这种方式简化了编程模型,但需要确保该内存区域被标记为不可缓存 (Uncacheable),以避免 CPU 缓存导致的数据不一致。典型 MMIO 设备包括:
- PCIe 配置空间:映射到内存地址 0xE0000000 附近 (具体由 MCFG ACPI 表指定)。
- 帧缓冲 (Framebuffer):显卡显存映射到物理地址空间。
- APIC 寄存器:本地 APIC 映射到 0xFEE00000。
3.5 模式切换流程与 BIOS 初始化
BIOS 在启动过程中,会按照以下典型路径切换 CPU 模式:
- 上电复位:CPU 处于实模式,CS=0xF000, IP=0xFFF0,执行 BIOS 入口代码。
- 实模式初始化:设置堆栈、中断向量表 (IVT)、检测内存、初始化芯片组。
- 切换到保护模式:构建 GDT,设置 CR0.PE=1,远跳转刷新 CS 缓存。
- 保护模式初始化:设置页表 (可选)、加载 IDT、初始化 APIC、枚举 PCI 设备。
- 切换到长模式 (UEFI 64-bit):设置 EFER.LME=1,启用 PAE 分页,设置 CR0.PG=1。
- 长模式初始化:加载 64 位 IDT,执行 DXE 与 BDS 阶段。
- 从实模式切换到保护模式前,必须确保 GDT 已正确设置,且代码段描述符的 DPL 与当前 CPL 匹配。
- 从保护模式切换到长模式时,必须先启用 PAE 分页,且页表必须覆盖当前执行地址。
- 切换过程中,通常需要禁用中断 (CLI),避免在模式切换期间响应中断导致异常。
3.6 本章小结
本章覆盖了 x86/x64 体系结构的三大核心主题:CPU 运行模式、内存分段与分页、I/O 访问模型。实模式提供最直接的硬件访问能力,保护模式引入特权级与段保护,长模式则通过强制分页实现 64 位寻址。理解这些底层机制,是后续编写 BIOS 初始化代码、配置内存映射、以及实现固件服务的基础。在下一章中,我们将深入 BIOS 启动流程,从 POST 到 Boot Selection 的完整路径。