linux - Linux 如何在 x86-64 中支持超过 512GB 的虚拟地址范围?

标签 linux linux-kernel x86-64 mmu

Linux x86-64 的用户虚拟地址空间是 47 位长。这实质上意味着 Linux 可以映射具有大约 128 TB 虚拟地址范围的进程。

然而,让我感到困惑的是,x86-64 架构支持 ISA 为每个进程定义的 4 级分层页表(排列为基数树)。页表的根最多只能映射 512 GB 的连续虚拟地址空间。那么Linux如何支持超过512GB的虚拟地址范围呢?它是否为每个进程使用多个页表?如果是,那么对于一个进程,对于任何给定的进程,CR3(x86-64 的寄存器包含页表基址的地址)应该包含什么?我错过了什么吗?

最佳答案

The root of the page table can only map up to 512 GB of contiguous virtual address space. So how Linux can support more than 512GB of virtual address range? Does it uses multiple page tables for each process? If yes, then for a process what should the CR3 (x86-64's register to contain the address of the base of the page table) contain for any given process? Am I missing something?

我不知道“页表的根”是什么意思,但 x86-64 上的分页看起来像这样:

  • 页表 - 最低级别的分页结构。每个都有 512 个 8 字节条目 (PTE),描述一个 4 KiB 页面,因此 PT 描述 512 * 4 KiB = 2 MiB 内存(它也可以用作 2 MiB 页面,但让我们把它留给现在)。
  • 页目录 - 表,类似于 PT,包含 512 个 8 字节条目 (PDE) 指向 PT;因此,PD 描述了 512 * 2 MiB = 1 GiB 内存(它也可以作为 1 GiB 页面工作,类似于 PT)。
  • 页目录页表 - 类似于 PD,但包含 512 个 8 字节条目 (PDPTE) 指向 PD;因此,PDPTE 描述了 512 * 1 Gib = 512 GiB 内存。
  • PML4,最高级别的分页结构,是包含指向 PDPT 的 512 个 8 字节条目 (PML4E) 的表;因此,PML4 描述了 512 * 512 GiB = 256 TiB 内存。

我不知道 Linux 的确切内存映射,但可能较高的一半(从 -128 TiB 到 0 - 从 0xFFFF8000000000000xFFFFFFFFFFFFFFFF)是为内核保留的,下半部分(从 0 到 128 TiB - 从 0x00000000000000000x00007FFFFFFFFFFFF)用于用户空间应用程序。因此,Linux 支持您要求的 512 GiB 虚拟地址范围的 512 倍;甚至 Torvalds 也不会说“我们不会支持 PML4”。我不知道是什么让你感到困惑 - 是不是你错过了说页表映射 2 MiB 的部分并且你已经把它映射了一页 - 4 KiB - 但如果有什么我可以澄清的,请询问

关于linux - Linux 如何在 x86-64 中支持超过 512GB 的虚拟地址范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11246559/

相关文章:

linux - Bash 脚本在文件名中生成项目符号

linux-kernel - cgroup 之外的进程是否可以访问 cgroup 隔离资源

assembly - 在 x64 中,使用 "pop [RAX]",值临时存储在哪里?

assembly - NASM x86_64 scanf 段错误

c - 编写单个生产者/单个消费者队列的最有效方式

linux - 服务器上的 Cron 脚本错误

java - 如何将java打印行移动到控制台窗口的顶部?

linux - 是否有任何约定可以将不同软件的部分可持续地放置在一个文件中

c - 在 Linux 中构建系统调用。内核 > 3.x.x

memory - 平板系统和伙伴系统有什么区别?