Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 64bit 系统)

Posted 范桂飓

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 64bit 系统)相关的知识,希望对你有一定的参考价值。

目录

文章目录

虚拟地址格式与内核页表(四级页表)

在 x86 64bit 系统中,可以描述的最长地址空间为 2^64(16EB),远远超过了目前主流内存卡的规格,所以在 Linux 中只使用了 48bit 长度,寻址空间为 2^48(256TB),User Space 和 Kernel Space 各占 128T。寻址空间分别为:

  • User Space:0x0000 0000 0000 0000~0x0000 7FFF FFFF F000,高 16bit 全 0。
  • Canonical Address Space:0x0000 7FFF FFFF F000 - 0xFFFF 8000 0000 0000,无效地址空间。
  • Kernel Space:0xFFFF 8000 0000 0000~0xFFFF FFFF FFFF FFFF,高 16bit 全 1。

由于内存空间的扩大,x86 64bit 系统中的虚拟地址格式由 5 部分组成,占 64bit 中的 48bit。相应的,Linux Kernel 在 v2.6.10 中实现了四级页表,后来又在 v4.11 中引入了五级的页表结构。

就四级页表而言,虚拟内存空间被划分成了 4 个层次结构,每一级都有一个页表来记录该层次的映射关系。

  1. PGD(Page Global Directory,全局页目录)
  2. PUD(Page Upper Directory,上级页目录)
  3. PMD(Page Middle Directory,中间页目录)
  4. PTE(Page Table Entry,页表项)

当 CPU 需要访问一个虚拟地址时,会执行以下页表遍历流程:

  1. 首先根据虚拟地址的 GLOBAL DIR(9bit),确定在 PGD 中的页表项,开始寻址 PUD。
  2. 再根据虚拟地址中的 UPPER DIR(9bit),确定 PUD 中的页表项,开始寻址 PMD。
  3. 再根据虚拟地址中的 MIDDLE DIR(9bit),确定 PMD 中的页表项,开始寻址 PTE。
  4. 再根据虚拟地址中的 TABLE ID(9bit),确定 PTE 中的页表项,开始寻址 Physical Page(物理内存页框)。
  5. 最后根据虚拟地址中的 OFFSET(12bit),确定 Physical Page 中的 Page Lane(页条)。

在页表遍历的过程中,如果找到对应的物理页框,则可以进行对应的内存读写操作。反之,如果遇到了寻址失败的情况,则说明对应的物理页框没有被分配或者被换出到外存了,此时需要进行相应的页表调度和页表交换操作。

四级页表的优点是它可以映射非常大的虚拟内存空间,并且每个进程的页表都是独立的,相互干扰。缺点是每次访问内存都需要遍历四级页表,这会导致一定的性能损失。并且,当 Linux 设定的虚拟页大小越小时,单个进程中的页表项和虚拟页也就越多,页表的层级也可能越多,查询性能就越低。同时也需要注意,页面并非是越大越好,因为过大的页面会造成内存碎片,降低了内存的利用率。

因此,Linux 采用了一些优化措施,如 TLB(Translation Look-aside Buffer)缓存等,来加速页表遍历的过程。

以上是关于Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 64bit 系统)的主要内容,如果未能解决你的问题,请参考以下文章

Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 32bit 系统)

Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 32bit 系统)

Linux 操作系统原理 — 内存 — 物理存储器与虚拟存储器

Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 64bit 系统)

Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 64bit 系统)

Linux glibc内存管理:用户态内存分配器——ptmalloc实现原理