ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux 学习笔记(三十八):从实模式到分页——处理器内存管理的发展史

Linux 学习笔记(三十八):从实模式到分页——处理器内存管理的发展史

📌 核心结论(TL;DR):

  1. 实模式(8086):16位寄存器通过“段基址左移4位+偏移量”拼接出20位地址(最大寻址1MB)。

  2. 保护模式(80386):引入 GDT(全局描述符表)和段选择子。为了安全,加入了 Ring 0 ~ Ring 3 特权级。

  3. 平坦模型:因为 32 位寄存器可以直接寻址 4GB,操作系统干脆把段基址全设为 0,只靠偏移量寻址,名义上还保留段机制,实则已经“废掉”了分段。

  4. 分页机制:为了解决内存碎片问题,将内存划分为 4KB 的页,配合页表实现虚拟内存映射。CPU 中拿到的地址永远是虚拟地址。

一、 探索起源:8086 与实模式

早期的 8086 处理器是 16 位的,但地址总线是 20 位(能寻址 1MB 空间)。16 位寄存器怎么表示 20 位的地址呢?Intel 发明了“段基址 + 段内偏移”的模式:

  • 物理地址 = 段基址 << 4 + 段内偏移
    这种方式被称为实模式。虽然解决了寻址问题,但存在严重的安全隐患——用户程序可以直接访问操作系统的物理内存,把系统搞崩溃。

二、 走向安全:保护模式与 GDT

到了 80286/80386 时代,引入了保护模式。

  1. 全局描述符表(GDT):操作系统在内存里维护了一个数组,记录了各个段的信息(包括基地址、界限、权限等)。

  2. 段选择子:CPU 寄存器里不再存段基址了,而是存一个“索引”。通过索引去 GDT 查找真正的段描述符。

  3. 特权级(Ring):分为 Ring 0(内核态)到 Ring 3(用户态)。低权限程序想访问高权限内存,门儿都没有。

三、 走向平坦:分段机制的没落

到了 80386,寄存器和地址总线都变成了 32 位(可以直接寻址 4GB)。既然一个偏移量就能访问整个 4GB 空间,分段机制就显得多余了。
为了让老软件还能跑,Linux 采用了平坦模式(Flat Model):把所有的段基址都设置为 0。所以,所有的虚拟地址从 0 开始算起。

四、 精细化管理:分页机制(Paging)

虽然有了分段,但内存分配很容易产生“外部碎片”(比如内存里总共有 30MB 空闲,但不连续,导致一个 30MB 的程序放不进去)。
于是引入了分页机制:

  • 将物理内存切分为固定大小的页框(4KB)。

  • 将程序的虚拟地址切分为同样大小的页。

  • 通过页表,把连续的虚拟页映射到不连续的物理页框上。这下不仅没有了外部碎片,还顺带实现了“虚拟内存”(把不常用的页换到磁盘上,骗程序说内存无限大)。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进