2. x86计算机体系结构基础:CPU模式、内存地址空间与I/O机制
本章是BIOS/UEFI固件开发的基石。x86处理器从加电复位到操作系统启动,会经历多种CPU模式切换;内存地址空间的布局决定了固件、操作系统和硬件资源的映射关系;I/O端口与MMIO则是固件与外围设备通信的两大核心通道。理解这三部分,才能正确编写初始化代码、配置芯片组和加载操作系统。
2.1 CPU模式:实模式、保护模式与长模式
x86处理器自Intel 8086起,经历了16位、32位到64位的演进,形成了三种主要的CPU工作模式。BIOS/UEFI固件在启动过程中必须依次穿越这些模式。
| 模式 | 地址宽度 | 最大物理内存 | 段/页机制 | 典型用途 |
|---|---|---|---|---|
| 实模式 | 20位 | 1 MB | 段基址:偏移,无页 | BIOS早期初始化、MBR/VBR引导 |
| 保护模式 | 32位 | 4 GB | 段描述符 + 可选分页 | BIOS后期、传统OS内核、UEFI DXE阶段 |
| 长模式 | 64位 | ≥ 64 TB | 段基址强制0 + 4级/5级分页 | UEFI 64位运行时、现代OS内核 |
2.1.1 实模式(Real Mode)
处理器复位后默认进入实模式。该模式下CPU如同一个高速的8086:
- 地址计算:物理地址 = 段寄存器 × 16 + 偏移量,最大寻址1 MB(0x00000 ~ 0xFFFFF)。
- 段寄存器:CS、DS、ES、SS、FS、GS,每个段最大64 KB。
- 中断向量表(IVT):位于物理地址0x00000 ~ 0x003FF,共256个中断向量,每个4字节。
- BIOS数据区(BDA):位于0x00400 ~ 0x004FF,存放系统硬件参数。
2.1.2 保护模式(Protected Mode)
保护模式引入段描述符和分页机制,提供4 GB线性地址空间和硬件级保护:
- 段描述符:每个段由8字节描述符定义,包含基址、限长、类型、特权级(DPL)等属性。
- 全局描述符表(GDT):存放所有段描述符,由GDTR寄存器指向。
- 分页:可选启用,将线性地址转换为物理地址,支持4 KB/2 MB/4 MB页面。
- 特权级:Ring 0(最高,内核/固件)~ Ring 3(最低,应用程序)。
2.1.3 长模式(Long Mode)
长模式是x86-64架构的原生64位模式,也是UEFI固件运行的主要模式:
- 地址空间:线性地址48位(当前实现),物理地址最高52位(取决于CPU)。
- 段基址强制为0:CS、DS、ES、SS的基址被忽略,分页成为唯一地址转换机制。
- 4级/5级分页:PML4 → PDPT → PD → PT(4级),或增加PML5(5级)。
- 兼容性子模式:长模式下可运行32位代码(CS.L=0, CS.D=1),用于执行传统Option ROM。
2.2 内存地址空间布局
x86处理器的物理地址空间并非全部映射为DRAM。芯片组和固件将地址空间划分为多个区域,用于映射内存、MMIO、固件ROM、ACPI表等。理解这个布局是BIOS开发的核心技能。
2.2.1 传统1 MB以下布局(实模式可见)
| 地址范围 | 大小 | 用途 |
|---|---|---|
| 0x00000000 ~ 0x000003FF | 1 KB | 中断向量表(IVT) |
| 0x00000400 ~ 0x000004FF | 256 B | BIOS数据区(BDA) |
| 0x00000500 ~ 0x00007BFF | 约30 KB | 常规内存(可用) |
| 0x00007C00 ~ 0x00007DFF | 512 B | MBR/VBR引导扇区加载地址 |
| 0x0000E000 ~ 0x0000FFFF | 8 KB | BIOS扩展数据区(EBDA) |
| 0x000A0000 ~ 0x000BFFFF | 128 KB | VGA显存(MMIO) |
| 0x000C0000 ~ 0x000C7FFF | 32 KB | VGA BIOS Option ROM |
| 0x000E0000 ~ 0x000FFFFF | 128 KB | 系统BIOS ROM(影子内存) |
2.2.2 4 GB以下布局(保护模式视角)
在32位保护模式下,物理地址空间0 ~ 4 GB的典型划分如下:
- 0x00000000 ~ 0x0009FFFF:常规内存(640 KB),DOS兼容区域。
- 0x000A0000 ~ 0x000FFFFF:传统ISA/PCI MMIO区域(384 KB),包括VGA、Option ROM、BIOS ROM。
- 0x00100000 ~ 0x0FFFFFFF:扩展内存(约256 MB - 1 MB),可被操作系统使用。
- 0x10000000 ~ 0xFEBFFFFF:PCI/PCIe MMIO、APIC、HPET等设备映射。
- 0xFEC00000 ~ 0xFFFFFFFF:系统保留区域(LAPIC、IOAPIC、SPI闪存、ACPI等)。
2.2.3 64位长模式地址空间
长模式下线性地址空间分为用户空间(0x0000000000000000 ~ 0x00007FFFFFFFFFFF)和内核空间(0xFFFF800000000000 ~ 0xFFFFFFFFFFFFFFFF)。物理地址空间则取决于芯片组:
- 4 GB以下:与传统布局兼容。
- 4 GB ~ 64 GB:扩展内存(需要PAE或长模式分页)。
- 64 GB以上:PCIe MMIO、内存映射设备等(具体由芯片组寄存器配置)。
2.3 I/O端口与MMIO
x86架构提供两种与外围设备通信的方式:I/O端口(Port I/O)和内存映射I/O(MMIO)。BIOS固件在初始化过程中大量使用这两种机制。
2.3.1 I/O端口(Port I/O)
I/O端口是x86特有的独立地址空间,使用专用指令访问:
- 地址空间:16位地址,共65,536个端口(0x0000 ~ 0xFFFF)。
- 访问指令:
IN(读)、OUT(写)、INS/OUTS(串操作)。 - 典型端口:
- 0x0060 ~ 0x0064:键盘控制器(8042/EC)
- 0x00A0 ~ 0x00A1:从片PIC(8259A)
- 0x00CF8 ~ 0x00CFC:PCI配置空间访问(CF8=地址,CFC=数据)
- 0x0080:POST码输出(用于调试)
; 示例:通过I/O端口读取键盘状态
IN AL, 0x64 ; 读取键盘控制器状态寄存器
TEST AL, 0x01 ; 检查输出缓冲区是否满
JZ no_key ; 如果为空,跳转
IN AL, 0x60 ; 读取键盘扫描码
2.3.2 内存映射I/O(MMIO)
MMIO将设备寄存器映射到物理地址空间,CPU使用普通的MOV指令访问:
- 优点:无需特殊指令,可配合缓存策略(UC/WC/WT/WB)使用。
- 缺点:占用物理地址空间,需要页表正确配置MTRR/PAT。
- 典型设备:
- VGA帧缓冲:0x000A0000 ~ 0x000BFFFF
- PCIe配置空间:通过MMIO方式(ECAM)访问,基址由芯片组寄存器设定
- LAPIC:0xFEE00000 ~ 0xFEEFFFFF
- IOAPIC:0xFEC00000 ~ 0xFECFFFFF
- SPI闪存控制器:通常在0xFED00000附近
2.3.3 PCI配置空间访问
PCI/PCIe设备的配置空间是BIOS初始化的核心。x86提供两种访问方式:
| 方式 | 访问方法 | 地址范围 | 适用场景 |
|---|---|---|---|
| I/O端口(CF8/CFC) | 写地址到0xCF8,读写数据到0xCFC | Bus 0~255, Dev 0~31, Func 0~7 | 传统PCI,兼容性好 |
| MMIO(ECAM) | 直接内存访问,基址由MCFG表指定 | Bus 0~255, Dev 0~31, Func 0~7 | PCIe,速度快,支持扩展配置空间 |
// C语言示例:通过CF8/CFC读取PCI配置空间
uint32_t pci_read_config(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset) {
uint32_t address = (1UL << 31) | (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xFC);
outl(0xCF8, address);
return inl(0xCFC);
}
2.4 本章小结
本章覆盖了x86计算机体系结构的三个核心基础:
- CPU模式:实模式(1 MB寻址,无保护)→ 保护模式(4 GB,段页保护)→ 长模式(64位,分页强制)。BIOS/UEFI启动路径必须依次穿越这些模式。
- 内存地址空间:物理地址空间被划分为常规内存、传统MMIO、扩展内存、PCI MMIO和系统保留区。固件必须正确管理这些区域,避免冲突。
- I/O机制:I/O端口(IN/OUT指令)和MMIO(内存访问)是设备通信的两种方式。PCI配置空间访问是BIOS初始化的关键操作。