跳转到内容

微处理器设计/虚拟内存

来自维基教科书,开放的书籍,为开放的世界
虚拟内存图。

虚拟内存是一种计算机概念,其中主内存被分成一系列独立的页面。这些页面可以作为单位在内存中移动,或者甚至可以移动到辅助存储器,以便为主内存腾出空间以用于新数据。本质上,虚拟内存允许计算机使用比可用内存更多的 RAM。

如果一个简单的虚拟==物理地址路径足以满足你的 CPU,你就不需要虚拟内存。

大多数处理器都具有非常简单的地址路径——地址位来自 PC 或其他一些程序员可见的寄存器,或者直接来自某些指令,并且它们直接应用于地址总线。

许多通用处理器都具有更复杂的地址路径:用户级程序运行时,就好像它们具有简单的地址路径一样,但应用于地址总线的物理地址与程序员可见的地址有很大不同。这使得虚拟内存、内存保护和其他理想功能成为可能。

如果你的 CPU 需要这样做,那么你需要一些东西来将用户可见的地址转换为物理地址——要么设计 CPU 连接到一些片外存储器寄存器或 MMU(例如 8722 MMU 或 68851 MMU),要么设计一个片上存储器寄存器或 MMU。

你可能希望这样做是为了

  • 支持各种调试工具,这些工具会捕获对选定地址的读或写操作。
  • 允许访问比用户级地址似乎支持的更多的 RAM(更宽的物理地址)(存储器分段)
  • 支持许多不同的程序同时在 RAM 中运行,但位于不同的物理 RAM 位置,即使它们都被编译为在位置 0x300 运行。
  • 允许程序使用正常的 LOAD 和 STORE 指令成功读取和写入一大块数据,就好像它都在 RAM 中一样,即使机器没有那么多的 RAM(分页和虚拟内存)
  • 支持一个“受保护的”监督级系统,它可以以全速运行有缺陷或恶意的用户级代码,使其处于隔离的沙箱中,而不会损坏其他用户级程序或监督系统本身——Popek 和 Goldberg 虚拟化、W xor X 内存保护等。
  • 或者上述几种情况的组合。

虚拟内存既可以在硬件中实现,也可以(在较小程度上)在软件中实现,尽管许多现代实现都具有硬件和软件组件。我们在这里讨论虚拟内存,因为许多现代 PC 和服务器处理器都具有内置的虚拟内存功能。

分页系统被设计为透明的,也就是说,在微处理器上运行的(用户模式)程序不需要显式地感知分页机制才能正常运行。

许多处理器系统为页面赋予某些限定符,以指定可以在页面中存储哪些类型的数据。例如,许多新处理器指定页面是否包含指令或数据,以便数据页面不能作为指令执行,而指令不能被数据写入破坏(参见 W^X)。


虚拟内存的硬件部分称为内存管理单元 (MMU)。大多数 MMU 的粒度为一个页面。

一些 CPU 设计使用更细粒度的访问控制来检测和防止缓冲区溢出错误,这是一种常见的安全漏洞。[1]

内存访问

[编辑 | 编辑源代码]

内存地址对应于特定页面,以及该页面内的偏移量。如果一个页面在 32 位计算机中为 212 字节,那么内存地址的前 20 位是页面地址,而较低的 12 位是该页面内数据的偏移量。在这种情况下,最上面的 20 位将与地址分离,并将被替换为该页面的当前物理地址。如果页面不存在于主内存中,处理器(或分页软件)将从辅助存储器中检索页面,这会导致显著的延迟。

页面是内存的基本单位,通常为几千字节或更大。页面可以在内存中移动到不同的位置,或者如果它没有被使用,它可以经常移动到辅助存储器。辅助存储器中的区域通常称为页面文件、“草稿板”或类似的名称。

各种页面的地址存储在一个分页表中。分页表本身可以存储在处理器内部的内存单元中,也可以驻留在主内存的专用区域中。

缺页错误

[编辑 | 编辑源代码]

当处理器无法在页表中找到页面时,就会发生缺页错误。

转换后备缓冲器

[编辑 | 编辑源代码]

转换后备缓冲器 (TLB) 是一种小型结构,类似于高速缓存,它存储最近使用页面的地址。在 TLB 中查找页面比在页表中搜索页面快得多。当处理器在 TLB 中找不到特定页面时,称为“TLB 未命中”。当 TLB 未命中时,处理器将在页表中查找页面。如果页面也不在表中,则会发生缺页错误。

请注意,即使 TLB 可以被认为是一种高速缓存,它缓存了存储在主内存中的页表的一部分,但它是一个与指令高速缓存或数据高速缓存物理上分离的结构,并且具有那些高速缓存中没有的几个特性。

TLB 条目

[编辑 | 编辑源代码]

TLB 中的 SRAM 可以被看作完全由 TLB 条目组成。TLB 中的 TLB 条目的格式由 TLB 硬件固定。分页监督程序——操作系统的一部分——通常在主内存中维护一个页表,该页表以与 TLB 条目完全相同的格式存储页表条目。每个 TLB 条目都包含

  • 页面的虚拟地址(类似于高速缓存中的“标记”)
  • 页面的物理地址(类似于高速缓存中的“数据”)

虽然不是必需的,但一些 TLB 硬件在 TLB 中具有许多其他可选的控制和保护字段和标志,包括

  • 不可执行位(NX 位),用于实现 W^X(“写入 XOR 执行”)
  • “脏位”(也称为“修改位”),在每次写入该页面的 STORE 时都会设置,并且通常在修改后的页面被写入备份存储器时清除。
  • 可写位,用于实现 PaX,有时由操作系统清除然后设置,以实现写时复制 (COW)
  • 物理页面所属的虚拟地址空间(在单地址空间操作系统 上不需要)
  • 监督位
  • 关于哪些 TLB 条目最近或最常被使用统计信息,用于决定在从主内存加载新的 TLB 条目时丢弃哪个 TLB 条目
  • 关于哪些页面最近或最常被使用统计信息,用于支持 LRU 或更复杂的页面替换算法,这些算法决定在操作系统需要将备份存储器中的其他页面加载到物理内存时,当前在主内存中的哪个页面“换出”到备份存储器

页表条目可能包含不会复制到 TLB 条目的其他每页字段,例如

  • “固定位”(又称“固定标志”),表示页面必须保留在主内存中——分页监督程序将分页监督程序可执行代码本身、用于辅助存储设备的设备驱动程序(页面被交换到这些设备上)、中断处理程序可执行代码标记为固定页面。一些数据缓冲区在设备在 CPU 外部读取或写入这些缓冲区(直接内存访问和 I/O 通道硬件)期间也处于固定状态。
  • “存在”位(当特定虚拟页面当前不存在于物理主内存中时清除)

进一步阅读

[编辑 | 编辑源代码]
  1. Albert Kwon, Udit Dhawan, Jonathan M. Smith, Thomas F. Knight, Jr. 和 André DeHon。 "低脂肪指针:紧凑编码和高效门级实现用于空间安全和基于能力的安全性的胖指针"。2013 年。
华夏公益教科书