从内部看Linux内核:理解页表和页表缓存的工作原理

一、概述

1.1、Linux内核页表的基本原理

Linux内核页表是一种数据结构,用于将虚拟地址映射到物理地址。在计算机系统中,应用程序使用虚拟地址来访问内存,而操作系统则需要将这些虚拟地址转换为物理地址,以便正确地读写内存。

Linux内核页表的基本原理是通过将虚拟地址分解为多个级别的索引来实现映射。每个级别对应一个页表项(Page Table Entry),其中包含了指向下一级页面的指针和其他相关信息。最终,所有级别的页表项都指向一个物理页面,并且该物理页面的内容即为应用程序所需的数据。

由于Linux内核支持32位和64位体系结构,因此它使用不同数量的页表级别。例如,在32位架构中,Linux使用三级页表结构,其中第一级是Page Global Directory(PGD),第二级是Page Middle Directory(PMD),第三级是Page Table(PT)。在64位架构中,则使用四级页表结构。

相关概念:
【页】:进程中的块。
【页框】:内存中的块。
【页表】:特殊数据结构,存放系统空间的页表区域(存放逻辑页与物理页帧的对应关系)。每个进程都有自己的页表,PCB 表中有指针指向页表。

1.2、页表缓存的作用及重要性

页表缓存(Page Table Cache,简称PTC)是操作系统中一种重要的缓存机制,用于加速虚拟内存管理过程中的页表查找操作。

当应用程序访问一个虚拟地址时,需要经过多次页表查找才能确定对应的物理地址。如果每次都直接访问主存中的页表数据,会导致严重的性能瓶颈。而通过使用页表缓存机制,在第一次页表查找后将结果保存在缓存中,下一次访问同样的虚拟地址时可以直接从缓存中读取数据,避免了不必要的主存访问。

页表缓存对系统性能具有重要作用。通过减少不必要的主存访问和提高查询效率,可以大幅度提升系统整体性能和响应速度。特别是在大型服务器和高负载场景下,这种优化效果更为显著。

此外,页表缓存还有助于减少内核开销和降低内核抖动概率。由于操作系统需要频繁地进行虚拟内存管理工作,并且涉及到大量的页表查询操作,因此优化这些操作对整个系统稳定性也非常关键。

二、Linux内核页表结构

在Linux内核中,页表是用来管理虚拟内存和物理内存之间映射关系的数据结构。Linux采用了两级页表(two-level page table)的结构,具体包括以下几个部分:

  1. PGD:全局页目录表(Page Global Directory),也称为一级页表(Level 1 Page Table),每个进程只有一个PGD,它保存了所有PMD所在的地址,每个PGD占据4KB大小。

  2. PMD:中间页目录表(Page Middle Directory),也称为二级页表(Level 2 Page Table),每个进程可以有多个PMD,一个PMD管理512GB的虚拟地址空间,每个PMD占据4KB大小。

  3. PTE:页面表项(Page Table Entry),也称为三级页表(Level 3 Page Table),每个进程可以有多个PTE,一个PTE管理4KB的虚拟地址空间,它保存了虚拟地址与物理地址之间的映射关系、权限信息等重要信息,每个PTE占据8字节大小。

  4. 页面框架:页面框架是操作系统分配给应用程序使用的基本单位,在x86架构下通常为4KB大小。页面框架可以被映射到任何虚拟地址上,并且一个页面框架可能会被多个虚拟地址映射到不同的位置。

通过上述结构,Linux内核可以对虚拟地址与物理地址之间的映射关系进行管理和维护。在应用程序访问虚拟地址时,内核会根据页表结构查找到对应的物理地址,并将数据读取或写入该物理地址中。同时,Linux内核还提供了一些优化技术,例如页表缓存、大页面、延迟分配等,以进一步提高系统性能和稳定性。

2.1、页表项

(1)逻辑地址(页号,偏移量),逻辑地址就是虚拟地址。比如二级页表的页表项如下:
在这里插入图片描述

(2)物理地址(页框号,偏移量)。映射关系如下:
在这里插入图片描述

2.1、各种类型的页面

  1. Page Table Entry (PTE):是操作系统中用于管理虚拟内存的一种数据结构。它记录了一个页面在物理内存中的地址,以及该页面所属的进程、权限等信息。

  2. Page Global Directory (PGD):是一种高级页表结构,用于管理大量虚拟内存。PGD可以将多个Page Table组织起来,形成一个更大的虚拟地址空间。

  3. Page Middle Directory (PMD):与PGD类似,PMD也是一种高级页表结构,但它比PGD粒度更小。PMD通常用于管理某个区域内的虚拟内存。

  4. Inverted Page Table (IPT):与传统的页表不同,IPT是以物理地址为索引来组织每个页面对应的虚拟地址和进程信息。这样可以减少页表占用的内存,并提高查找效率。

  5. Translation Lookaside Buffer (TLB):是一种高速缓存,用于加速虚拟地址到物理地址的转换过程。TLB通常位于CPU芯片上,并具有非常快速的访问速度。

三、虚拟地址到物理地址的映射过程

3.1、虚拟地址到物理地址转换机制

(1)当应用程序需要访问内存时,会生成一个虚拟地址。这个虚拟地址由两个部分组成:页号和偏移量。
在这里插入图片描述
(2)操作系统将虚拟地址中的页号与页面表进行匹配,找到对应的Page Table Entry(PTE)。
(3)如果PTE中记录了该页面在物理内存中的位置,则操作系统将物理内存地址和偏移量组合成一个物理地址,并返回给应用程序。如果PTE中未记录该页面在物理内存中的位置,则产生一个缺页异常。
在这里插入图片描述
(4)在发生缺页异常时,操作系统会尝试从磁盘或其他存储设备上加载相应页面,并更新PTE以反映新页面所处的位置。
在这里插入图片描述

(5)一旦新页面加载到物理内存中,操作系统就可以使用步骤3中描述的方式来计算出该页面在物理内存中的位置,并返回给应用程序。

这样,在之后访问同一段虚拟地址时,就不需要再次发生缺页异常,而是直接查找PTE并返回对应的物理地址。

3.2、线性地址和虚拟地址之间的关系

线性地址是CPU产生的地址,它是由段选择符和偏移量组成。在进行内存访问时,CPU会将线性地址转换为物理地址,并将数据从物理内存中读取或写入。因此,线性地址是在CPU内部使用的,不直接对应物理内存中的位置。

而虚拟地址则是应用程序使用的地址,它也由两部分组成:页号和偏移量。虚拟地址对应了应用程序所需访问的具体数据块在逻辑上的位置。操作系统会负责将虚拟地址转换为物理地址,并实现内存访问。

在这个过程中,操作系统采用了一些技术来实现虚拟地址到物理地址的转换。例如,在32位x86架构中常用的方法是利用分页机制(paging),将整个逻辑空间划分为大小相等、连续编号的页面(page)。每个页面包含若干个字节,并且与一个PTE相对应。PTE记录了该页面是否已经加载到物理内存中以及其在物理内存中的位置等信息。

当应用程序需要访问某个虚拟地址时,操作系统首先根据虚拟地址的页号查找PTE,如果该页面已经在物理内存中,则可以通过PTE计算出对应的物理地址,并将数据从物理内存中读取或写入。否则,就会发生缺页异常,并且操作系统需要将相应页面从磁盘或其他存储设备上加载到物理内存中。

因此,线性地址和虚拟地址之间存在一定的关系。在32位x86架构中,线性地址是由段选择符和偏移量组成的,而偏移量部分直接对应了虚拟地址的偏移量部分。同时,在进行内存访问时,CPU会自动执行线性地址到物理地址的转换,并且可以利用硬件支持来提高访问速度。

在这里插入图片描述

四、页表缓存原理

【页表缓存】:CPU 内存管理单元(MMU),处理器制造厂商在内存管理单元中增加的一个高速缓存(称为页表缓存)。作用将虚拟地址转换成物理地址。
在这里插入图片描述
页表缓存(Page Table Cache)是一种高速缓存,用于存储最近使用的页表项。在虚拟内存系统中,每个进程都有一个页表来将虚拟地址映射到物理地址。由于访问页表项需要访问主存储器,因此使用页表缓存可以减少对主存储器的访问次数,提高系统性能。

其意义在于:

  1. 提高了访问速度:通过将最常用的页表项缓存在高速缓存中,可以快速地读取和更新它们,从而大大降低了访问主存储器的次数,并加快了访问速度。

  2. 节约了系统资源:由于避免了频繁地读取和更新主存储器中的页表项,所以可以减轻CPU、内存等硬件资源的负担。

  3. 增加了应用程序可用性:当多个进程同时运行时,使用页表缓存可以避免不必要的竞争和冲突,并增加应用程序可用性。

不同级别的缓存技术主要包括以下几种:

  • L1缓存:L1缓存是CPU内部的一种高速缓存,它通常使用SRAM技术。由于L1缓存与CPU核心相连,因此可以极大地提高访问速度。
  • L2缓存:L2缓存位于CPU和主内存之间,通常采用DRAM技术。它比L1缓存容量更大,但速度较慢。
  • L3缓存:L3缓存在多个CPU之间共享,并且位于主板上。与L2缓存相比,它具有更大的容量和较低的成本。
  • 主内存:主内存在计算机系统中是最慢的储存器之一。为了提高数据访问速度,在主内存中使用了多种优化技术,如页表映射、虚拟地址等。
  • 磁盘/SSD:磁盘和固态硬盘(SSD)通常用作长期储存设备。由于其较低的读写速度,因此通常需要在操作系统或文件系统中进行优化以提高性能。

Linux内核页表及页表缓存是内存管理机制的核心组成部分,其作用是将虚拟地址映射到物理地址。在Linux内核中,每个进程都有自己的虚拟地址空间,因此需要进行地址转换,以便将虚拟地址映射到实际的物理地址上。

Linux内核中的页表是存储虚拟地址和物理地址之间映射关系的数据结构。每个进程都有自己的页表。当进程访问某个虚拟地址时,内核会根据该虚拟地址对应的页表项找到其对应的物理地址,然后将其映射到物理内存中。

为了提高性能,Linux内核引入了页表缓存的概念。页表缓存是存储页表项的高速缓存,用于加速页表项的查找和访问。当进程访问一个虚拟地址时,内核会首先查找页表缓存,如果页表缓存中已经有该页表项,则可以直接使用,否则需要访问页表获取该页表项,并将其保存到页表缓存中。

Linux内核页表及页表缓存的作用是实现虚拟地址到物理地址的映射,以及提高地址转换的效率和性能。在实际应用中,合理配置页表大小和页表缓存大小等参数,可以有效地提高系统的性能和可靠性。同时,Linux内核中的内存管理机制是一个很复杂的系统,需要深入理解其原理和作用,才能更好地进行系统优化和调优。

五、它们的关系

  1. 页表由多个页表项构成,页表中每一行为一个页表项。
  2. 页框号:专门用于存储虚拟页面对应的物理页面。
  3. 页表项由硬件设计。
  4. 页目录,为页表提供目录(二维结构),支持多级查找。当一个应用程序在CPU上运行时,需要将页目录的起始地址放到寄存器中(因为虚拟地址的转换过程需要偏移量)。
  5. MMU的工作过程:CPU 获取虚拟地址–>MMU 查询页目录–>MMU 查询页表–>MMU 获取页表项–>MMU 获取到物理页面编号–>MMU 获取物理地址。

总结

Linux内核的页表及页表缓存原理主要包括以下几个方面:

  1. 页表:Linux内核使用了多级页表机制,通过将物理地址映射到虚拟地址来实现对系统内存的管理。在这种机制下,每个进程都有自己的页表结构,用于将其虚拟地址映射到物理地址。Linux内核中采用了4级或3级页表结构。

  2. 页表项:每个页面都会对应一个页表项,其中包含了该页面所属的物理帧号、标志位等信息。

  3. TLB:为了提高访问效率,Linux内核引入了TLB(Translation Lookaside Buffer)缓存机制。TLB是一个小型的高速缓存,用于保存最近访问过的一些页面的映射关系。当CPU需要访问某个虚拟地址时,先查找TLB缓存中是否已经有对应的物理地址映射关系。如果存在,则可以直接从TLB中获取该映射关系;否则就需要重新查询相应的页表项,并更新TLB缓存。

  4. 页表缓存:由于访问主内存比访问TLB更耗时,在向上级别查询之前,内核会首先搜索一个称为"pte_highmem"的特殊数据结构来检查是否存在与该虚拟地址匹配的页表项。该数据结构充当了一个页表缓存的角色,可以显著减少查询页表时需要进行的主内存访问次数。
    在这里插入图片描述

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
ARM架构的Linux页表代码实现主要涉及到以下几个文件: 1. `arch/arm/include/asm/pgtable.h`:定义了ARM架构下的页表相关宏和数据结构,包括页表项(PTE)和页目录项(PMD)的定义。 2. `arch/arm/mm/pgtable.c`:实现了ARM架构下的页表相关函数,包括页表初始化、页表项/页目录项的创建和修改等。 3. `arch/arm/mm/mmu.c`:定义了ARM架构下的内存管理单元(MMU)的初始化和配置函数,包括页表的设置和切换等。 在ARM架构下,页表使用两级结构,包括页目录表(Page Directory Table)和页表(Page Table)。每个级别的表都有对下一级表的指针,最终指向物理内存中的页帧。 ARM架构中的页表项(PTE)和页目录项(PMD)由特定位字段组成,用于保存物理地址、标志位和其他控制信息。页表项和页目录项的结构可以在`arch/arm/include/asm/pgtable.h`中找到。 在ARM架构下,通过`pgd_offset`、`pmd_offset`、`pte_offset`等函数可以计算出对应虚拟地址在页表中的索引,并通过这些索引来获取或设置相应的页表项或页目录项。 初始化页表时,可以调用`pgd_alloc`、`pmd_alloc`、`pte_alloc`等函数来创建页表项和页目录项,并通过`pgd_populate`、`pmd_populate`等函数将物理页框与虚拟地址进行映射。 ARM架构中的MMU初始化和配置主要通过`setup_mm_for_reboot`、`init_mmu`和`__create_page_tables`等函数完成。这些函数会设置页表寄存器(TTBR0/TTBR1)和控制寄存器(CRn),从而将页表切换到对应的地址空间。 需要注意的是,不同的ARM架构版本和具体的SoC可能会有一些细微的差异,因此具体的代码分析还需要参考相关的架构文档和代码实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lion Long

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值