Pentium处理器采用了分页的虚拟内存管理机制,其地址转换过程可以概括为“从虚拟地址到物理地址”的两级转换过程,这个过程由CPU的内存管理单元操作系统共同协作完成。

pentium处理器的地址转换
(图片来源网络,侵删)

核心概念:三种地址

在深入细节前,必须先理解三种地址的区别:

  1. 虚拟地址:由程序(CPU生成)使用的地址,它是一个逻辑地址,程序以为自己独占整个4GB的地址空间(在32位系统下),这是程序员和CPU日常打交道的地址。
  2. 线性地址:在x86架构中,虚拟地址经过分段机制转换后,会生成一个线性地址,在Pentium及以后的“平坦内存模型”(Flat Memory Model)下,虚拟地址和线性地址通常被认为是相同的,为了简化,我们后续将主要讨论从线性地址到物理地址的转换。
  3. 物理地址:内存芯片上的实际地址,数据真正存储在内存条上的位置。

我们的核心任务就是:虚拟地址 -> 物理地址


地址转换的硬件核心:分页机制

Pentium的分页机制将线性地址空间划分为固定大小的块,称为,同样,物理内存也划分为同样大小的页框,转换的目标就是找到虚拟地址所在的“页”对应物理内存中的哪个“页框”。

页的大小

  • Pentium处理器支持两种页大小:4KB4MB(仅在Pentium Pro及更高型号中支持)。
  • 我们主要分析最常见的4KB页

页表的结构

页表是实现地址转换的“地图”,它是一个存放在物理内存中的数据结构,由操作系统创建和维护。

pentium处理器的地址转换
(图片来源网络,侵删)

对于4KB的页,一个32位的线性地址被划分为三个部分:

31 - 22 21 - 12 11 - 0
页目录索引 页表索引 页内偏移
  • 页内偏移:12位,表示在4KB页内的具体位置 (2^12 = 4096)。
  • 页表索引:10位,用于在页表中查找对应的页表项。
  • 页目录索引:10位,用于在页目录中查找对应的页目录项。

为什么是两级? 如果只用一个巨大的页表,它需要包含 2^20 (约100万个) 条目,占用4MB内存,非常浪费,使用两级结构,可以按需创建页表,节省内存。


地址转换的详细步骤

整个过程由CPU的MMU自动完成,但需要操作系统预先设置好数据结构。

步骤1:定位页目录

  • CPU内部有一个特殊的寄存器,叫做页目录基址寄存器,它存储了页目录在物理内存中的起始地址。
  • 这个寄存器是受特权级保护的,只有操作系统内核(运行在最高特权级Ring 0)才能修改。

步骤2:查页目录,找到页表的物理地址

  1. CPU取出线性地址的高10位(31-22位),作为页目录索引
  2. 用这个索引去访问页目录,页目录本身就是一个数组,每个元素称为页目录项
  3. CPU将页目录的基址寄存器中的地址,加上 索引 * 4(因为每个PDE是4字节),计算出PDE在内存中的地址。
  4. 从内存中读取这个PDE,PDE的结构如下:
31 - 12 11 - 9 8 7 6 5 4 3 2 1 0
页表基址 AVL G PAT D A U/S R/W U/S P
(20位)
  • 最重要的字段是 P (Present) 位P=0,表示该页表不在内存中,会触发一个缺页异常,操作系统需要介入处理。
  • 最重要的字段是 页表基址:这是一个20位的物理地址,指向了页表的起始物理地址,CPU会将其扩展到32位(高位补零)。

步骤3:查页表,找到页框的物理地址

  1. CPU取出线性地址的中间10位(21-12位),作为页表索引
  2. 用上一步找到的页表基址,加上 索引 * 4,计算出页表项在内存中的地址。
  3. 从内存中读取这个PTE,PTE的结构和PDE非常相似:
31 - 12 11 - 9 8 7 6 5 4 3 2 1 0
页框基址 AVL G PAT D A U/S R/W U/S P
(20位)
  • P (Present) 位P=0,表示该页(即对应的代码或数据)不在内存中,触发缺页异常
  • 页框基址:这是一个20位的物理地址,指向了页框的起始物理地址。

步骤4:组合成最终的物理地址

  1. CPU取出线性地址的低12位(11-0位),作为页内偏移
  2. 将上一步找到的页框基址(20位)和页内偏移(12位)拼接起来。
  3. 物理地址 = 页框基址 + 页内偏移

CPU就得到了最终要访问的物理内存地址,并执行实际的内存读写操作。

pentium处理器的地址转换
(图片来源网络,侵删)

TLB:转换后备缓冲区

上述过程需要访问内存两次(一次查页目录,一次查页表),这会严重影响性能,为了解决这个问题,CPU引入了TLB

  • 什么是TLB? TLB是一个位于CPU内部的小型、高速的缓存,专门用于存储最近使用的线性地址到物理地址的转换结果(即PTE的内容)。
  • 工作流程
    1. CPU在执行地址转换前,首先检查TLB。
    2. TLB命中:如果转换结果在TLB中,CPU直接从中获取物理地址,整个过程只需1-2个时钟周期,非常快。
    3. TLB未命中:如果转换结果不在TLB中,CPU才执行上面描述的、较慢的两次内存访问来查找页目录和页表,找到后,会将新的转换结果存入TLB,以便下次使用。
  • TLB刷新:当操作系统修改了页表或页目录(一个进程被换出内存,它的页表被无效化),必须通知CPU刷新TLB中对应的条目,否则会使用错误的地址转换,这通过INVLPG指令实现。

操作系统的角色

硬件提供了机制,但操作系统必须提供策略。

  1. 初始化:操作系统启动时,为自己创建一个初始的页目录和页表,并设置好CR3寄存器。
  2. 进程切换:当切换到另一个进程时,操作系统必须将该进程的页目录的物理地址加载到CR3寄存器中,这样,后续的地址转换就会使用新进程的“地址地图”。
  3. 缺页处理:当发生缺页异常时,操作系统会介入:
    • 判断访问的内存页是合法的(即该进程的虚拟地址空间中确实有这个页)。
    • 如果合法,但数据在硬盘的交换空间中,则从硬盘读取数据到内存的一个空闲页框中。
    • 更新页表,将新的页框地址填入对应的PTE,并将P位置1。
    • 返回到用户程序触发异常的指令处重新执行。
  4. 内存管理:操作系统负责跟踪哪些物理页框是空闲的,哪些已被占用,以及它们属于哪个进程。

4MB大页支持

Pentium Pro引入了对4MB大页的支持。

  • 线性地址结构:线性地址只被分为两部分: | 31 - 22 | 21 - 0 | | :--- | :--- | | 页目录索引 | 页内偏移 |

  • 转换过程

    1. 用高10位索引查页目录,得到一个PDE。
    2. 这个PDE的P位如果为1,并且一个特殊位(PS位,Page Size)为1,则表示这是一个4MB的大页。
    3. CPU不再使用页表,而是直接用PDE中的20位页框基址和低20位的页内偏移组合成最终的物理地址。

优点:只需要一次内存访问(查页目录),转换速度快,TLB命中率更高。 缺点:灵活性差,内存浪费可能更严重(因为一个页很大,如果只用到其中一小部分,其他部分就浪费了)。

Pentium处理器的地址转换是一个高效而复杂的硬件与软件协作的典范:

  1. 硬件层面:MMU通过两级页表(页目录->页表)结构,将32位线性地址高效地转换为32位物理地址。TLB作为高速缓存,极大地加速了转换过程。
  2. 软件层面:操作系统负责创建、维护和切换页表结构,并处理缺页异常等特殊情况,为每个进程提供独立的、受保护的虚拟地址空间。

这个设计不仅解决了内存不足的问题,还实现了进程间的内存隔离和内存保护,是现代多任务操作系统的基石。