一个OS"deal in"虚拟地址和物理地址怎么算

How does an OS "deal in" virtual addresses and physical addresses

据我了解 Intel® 64 和 IA-32 架构 软件开发人员手册 第 3 卷(3A、3B、3C 和 3D): 系统编程指南,基于每个核心启用分页:关闭或打开。

因此,物理地址中的 OS "deal" 怎么办?最直接的是,它将如何管理页面 table 结构和关联的页面框架?

我能想到的两件事:

paging is enabled on a per-core basis: either off, or on.

是的,每个内核都有自己的一组控制寄存器。

The OS would, during startup, and before enabling paging, map a section of linear addresses directly to physical addresses.

通常,OS 会在启动期间启用分页。在此之前,它首先创建一个多级页面 table。必须至少有一个虚拟到物理页面的映射,这样当启用分页时,至少会有一个页面可以访问而不会触发页面错误。 OS则把第一级页table(页目录)的物理基地址存入CR3控制寄存器。最后,要真正启用分页,OS sets CR0[PG] to 1。当一条指令将 CR0[PG] 从 0 更改为 1 时,所有后续指令有效地开始使用分页单元(有一个例外,见下文)。这意味着 all 内核的地址生成单元生成并由分段单元(如果适用)映射到相应线性地址的有效地址被分页单元截获以映射到物理使用页面 table 的地址。这里的关键点是 CR3 包含一个物理地址,而不是逻辑地址或线性地址,这打破了地址转换的无限循环。

这意味着 OS 使用的数据结构及其代码也必须映射到虚拟页面。通常,每个进程的虚拟地址 space 被划分为用户模式部分和内核模式部分。每个进程的虚拟地址space的内核分区被映射到相同的物理页。为此,无论哪个进程调用内核,内核都可以使用相同的虚拟地址和调用进程的相同虚拟地址space。内核页面通过在其页面 table 条目中设置标志来保护。

The OS would actually disable paging to perform these types of tasks, then reenable it.

从技术上讲,OS 可以随时禁用分页。但这不是必需的。页面 table 本身也映射到虚拟地址,这样 OS 可以在不禁用分页的情况下维护它们。这是通过以一种称为 self-mapping or recursive mapping 的特殊方式设置一个一级页面 table 条目来完成的(这篇文章包含很好地解释了这个概念的好图)。

但是,分页可能会在 OS 无法控制的情况下被禁用。当系统管理模式中断 (SMI) 发生时,会发生这种情况,此时分页和保护模式分段均被禁用。 SMI 处理程序(由 OS 注册)在称为 SM 模式的特殊模式下运行,类似于实模式。从 SM 模式返回后,如果在 SMI 发生之前启用了保护模式分段和分页,它们将自动重新启用。

大多数操作系统将所有物理内存映射到一个虚拟地址范围,仅使用内核映射。例如https://www.kernel.org/doc/Documentation/x86/x86_64/mm.txt 是 Linux 的内存映射。

注意最大 64TB "direct mapping" 区域。如果你知道一个物理地址,你在内核虚拟地址 space.

中访问 0xffff880000000000 + phys_addr

Linux直接映射使用1G大页面,所以TLB miss很少见。


当没有足够的虚拟地址 space 来轻松地将所有物理 RAM 映射到虚拟地址 space 的一部分时,事情会变得复杂,例如 32 位内存超过 2GiB。然后内核必须将物理 RAM 的一部分视为 "highmem" 不能直接用于某些事情(例如页表)。