c - 进程页表

标签 c windows assembly x86 kernel

我有兴趣更深入地了解虚拟内存和页面机制,尤其是针对 Windows x86 系统。根据我从各种在线资源(包括 SO 上发布的其他问题)收集的内容,

1) 每个进程的单独页表位于同一进程的内核地址空间内。

2) 每个进程只有一个页表,包含虚拟页到物理页(或帧)的映射。

3) 内存管理单元(MMU)计算给定虚拟地址对应的物理地址,本质上是使用提供的虚拟地址的前20位作为页表的索引,使用该索引检索物理帧的起始地址,然后根据虚拟地址的剩余 12 位对该地址应用一些偏移量。

这三个说法正确吗?还是我误解了信息?

最佳答案

所以,首先让我们澄清一些事情:

  1. 在 x86 架构的情况下,决定分页策略的不是操作系统,而是 CPU(更具体地说是 MMU)。操作系统如何看待分页系统与其实现方式无关。正如一位评论者正确指出的那样,分页模型有一个特定于操作系统的组件。这从属于硬件的做事方式。
  2. 32 位和 64 位 x86 处理器具有不同的分页方案,因此如果不指定处理器的字长,就不能真正谈论 x86 分页模型。

接下来是 32 位 x86 分页模型的大规模压缩版本,使用它的最简单版本。还有许多其他可能的调整,我知道各种操作系统都在使用它们。我不打算深入这些,因为我并不真正熟悉大多数操作系统的内部结构,并且因为在掌握更简单的内容之前,您真的不应该深入了解这些内容。如果您想了解 x86 分页模型的所有精彩之处,您可以访问英特尔文档:Intel System Programming Guide

在最简单的分页模型中,内存空间被分成4KB大小的 block ,称为页。其中 1024 个连续 block 映射到一个页表(大小也是 4KB)。对于更进一步的间接级别,所有 1024 页表都映射到一个 4KB 页目录,该目录的基址位于处理器中的一个特殊寄存器 %cr3 中。这种两级结构之所以存在,是因为操作系统中的大多数内存空间稀疏,这意味着其中大部分未被使用。您不想为未触及的内存保留一堆页表。

当你得到一个内存地址时,最高有效的 10 位索引到页目录中,这给你页表的基础。接下来的 10 位索引进入该页表,为您提供物理页面(也称为物理帧)的基础。最后,帧的最后 12 位索引。假设您已将 %cr3 设置为正确的值,MMU 会为您完成所有这些工作。

64 位系统有一个4 级 分页系统,因为它们的内存空间要稀疏得多。此外,页面大小不是 4KB 也是可能的。

真正回答您的问题:

  1. 所有这些分页信息(表、目录等)都位于内核内存中。请注意,内核内存是一个大夹头,没有为单个进程提供内核内存的概念。
  2. 每个进程只有一页目录。这是因为页目录定义了一个内存空间,每个进程只有一个内存空间。
  3. 上面的最后一段向您介绍了地址的分割方式。

编辑:清理和小修改。

关于c - 进程页表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6627833/

相关文章:

c - 安全标识符 "directory"导致我的程序崩溃

c - freeBSD中rqhead类的定义在哪里?

c - 使用 __builtin_msa_ld_* 后如何转换为无符号 vector 类型

windows - Gitignore 不会忽略 Windows7/8 上 Visual Studio 2015 RC 的 .vs 文件夹

assembly - ARM 程序集 : auto-increment register on store

c - 警报(int)在 while 循环中不起作用

java - 如何创建作为 Windows 服务运行的 Java 进程的内存转储?

c# - 将开发从 Windows 转移到 Linux

winapi - 你推荐什么反汇编程序?

assembly - 如何在气体汇编代码中导出类型为 "FUNC"和 "GLOBAL"的符号?