相关推荐
内存管理源码分析-内核页表的创建以及索引方式(基于ARM64以及4级页表)
2024-12-26 05:02

简介

页表的主要作用是完成虚拟地址到物理地址的转换,更详细的介绍可以参考这个优秀的博客,很好地介绍了页表的理论。Linux如何实现这个页表理论呢?以及如何进行寻址呢?本文将会结合代码,从代码出发,基于ARM64的架构,分析Linux从源码上如何实现页表理论。

内存管理源码分析-内核页表的创建以及索引方式(基于ARM64以及4级页表)

从一个页的地址说起

对于ARM64的架构,一个虚拟地址的大小是64bit。但是实际上并不是全部64bit都是用来寻址的,其中一部分bit会基于架构的不同有不一样的作用,但是一个最基本的应用是区分当前地址是用户态还是内核态的地址。内核可以通过宏将用来寻址的bit的大小配置为36,39,42,47,48,52bit。不同的数目的寻址bit可以组成不同level的页表,可以参考上面推荐的博客,这里不做介绍。我们基于48bit的地址线大小结合4级页表,分析ARM64架构下的内存页是如何进行映射的。

假设目前有一个页,它的64bit虚拟地址是。由于内存是字节寻址的,因此我们可以以字节的形式进行访问,所以这个例子是:

访问这个页的第一个字节,地址是

访问这个页的第二个字节,地址是

访问这个页的第二个字节,地址是

他们只是尾部的数据有点不同,其他的位置没有变化,但是为什么会这样呢?

问题一: 这个虚拟地址隐藏了什么信息?

基于4级页表,可以知道页表共有4层映射关系,即、、、。页表首先会根据虚拟地址找到了,再从里面找,再从里面找,再从里面找,最后表的表项记录的是页的物理地址。、、、表的大小都是512,因此可以使用9bit来表示(1 << 9 = 512)每一个表的entry的位置信息。需要注意的是,前面提及的、、、表中,每一个表都包含一个8字节的表项,用于记录下一级表的索引信息。

由于表的表项记录的是页的物理地址,因此我们可以根据获得一个页。同时由于内存是字节寻址,我们还需要对这个页内的每一个字节进行寻址,因此Linux对页内的每一个字节的位置,使用来表示。如表示页内第一个字节,表示页内第二个字节。由于一个页的大小是4096字节,所以需要12bit来表示(1 << 12 = 4096)。最终,页内每一个字节的位置被这个12bit的地址信息全部表示出来。

根据前面分析,由此我们可以知道,内存里的每一个字节,是通过、、、以及进行索引的,它的总体结构如下:

1111111111111111000000011000000101000000111000001001000000000000

其中

值是,不用来直接寻址,一般是用来区分地址是用户态还是内核态,如全1表示内核态,全0表示用户态。

值是,十进制值是,因此。

值是,十进制值是,因此。

值是,十进制值是,因此。

值是,十进制是,因此。

值是,十进制是,因此,表示页内的第一个字节

以此类推,对于虚拟地址,以及,它们只是在处,即处不同,十进制值分别是和,分别表示页内的第二个字节以及第三个字节。

问题二: 虚拟地址是如何跟物理地址对应起来?

从问题一的论述,我们知道虚拟地址是通过一定的地址索引设计所组织起来,我们通过这个虚拟地址,可以找到内存中每一个字节在内存中的位置。但是实际上的物理内存是怎么分布的呢? 、、、等寻址表,又是怎么样进行索引到物理内存的地址呢?在探讨这个问题之前先介绍一下内核页表进程页表

内核页表和进程页表

前面提及的虚拟地址的用于区分当前地址是用户态的虚拟地址,还是内核态的虚拟地址。例如使用函数分配的地址就是用户态的虚拟地址,而函数分配的地址就是内核态的虚拟地址。Linux有两种类型的页表,分别是进程页表内核页表。进程页表是进程私有的页表,内核页表是所有进程共享的页表。内核页表在系统初始化的时候就会创建,而进程页表则会在用户态进程创建的时候将内核页表复制给当前的进程页表。当进程在用户态运行时,它使用的是进程页表。当进程在内核态运行时,它使用的是内核页表。

进程页表例子: 当一个用户态的进程通过分配了一个大小N个页内存区域A,然后通过指针不断访问内存空间A,此时由于程序在用户态运行,因此它使用的是进程页表进行寻址。

内核页表例子: 当进程写一个文件的时候,它会通过系统调用(如sys_write)进入内核态,此时就会使用内核页表进行寻址。

进程页表在内核对应的索引是而内核页表在内核的索引是中。内核页表的索引,最终会找到内核页表对应的结构,全局变量,它是一个数组(如下定义),记录了各个在物理内存位置,因此其实这个结构就是上图提及的映射表。

 
PGD、PUD、PMD、PTE的初始化

用于虚拟地址寻址的、、、等寻址表在系统建立虚拟地址和物理地址之间的映射关系时建立。其初始化的代码在的函数,请参考注释:

函数分析:

 
  1. 从上图以及上面代码可以知道,由于构建映射表需要512个表项,每一个表项的大小是8字节,因此需要4096字节空间才可以构建映射表。因此函数分配一个物理页(4K),用于构建临时的PGD映射表。由于页表是处于虚拟地址空间进行构建的,因此物理地址需要先转化为虚拟地址即。
  2. 完成内核进程地址空间的一些保留位置的映射,如.text,.data、.bss段等映射,同时完成映射的同时也会创建对应的、、、等。
  3. 完成、、、的,即创建映射,然后创建重点分析这个函数。
  4. 用于新的临时映射表已经构建完成,已经可以称为页表,因为临时表已经可以根据、、、找到对应的物理页。接下来就要替换旧的内核页表,因此首先调用函数以及函数完成页表的更新。内核页表中会在系统运行中一直维持着,因此当系统根据虚拟地址搜索时,首先就是访问这个表。内核页表可以通过进行访问,即是所有进程共享的页表。用户进程拥有自己私有的页表,这个私有页表的初始化的。
函数分析:
 

遍历所有的,对于一般嵌入式设备只有一个。然后将物理内存的起始地址和结束地址传入进去函数进一步处理。

 

这个函数将物理地址转换为虚拟地址,作为另外一个参数传入到函数。

 

再一次注意注意!分析这个函数之前,需要明确一点,上面的、、、的分析都是基于虚拟地址!因此,我们在计算、、、的时候,需要先将物理地址转换为虚拟地址。

是函数分配临时映射表的物理内存空间对应的虚拟地址,函数用于计算当前的内存起始地址属于映射表的第几个表项,然后将该表项作为指针传递出来,类似于:

下一步如注释所示,即获取该一段物理地址的低12位,然后获取虚拟地址的低12位,这样做的目的是让物理内存由原来的按字节计算,变为按页计算。从这里开始,物理内存的起始、物理内存的大小都是以页作为基本单位。接下来算出目前正在初始化的内存,一共包含多少个页,而且页的起始地址和结束地址是什么。

下一步进入循环,由于每一个包含512个,而每一个包含512,每一个包含512个,也就是512个页,因此一个的的表示范围很大,如下:

 

因此大部分情况下(内存少于512GB),只会有一个,也只会针对这个构建页表(因此节省了许多内存)。

下一步就是在该下通过函数构建表项:

 

这里传入参数就是映射表的对应的页表项指针,这个指针保存的值就是该对应的映射表的头地址。因此第一步通过获得映射表的头地址。然后通过函数基于计算出当前属于当前映射表的第几个表项,然后循环地在各个映射表表项建立对应的映射表Entry,如下。

 

同函数差不多,不多做解释,接着看下一个函数:

 

映射表的作用是直接记录物理页在内存的位置(即页帧号),每一个表项就记录了一个页帧号的信息。因此一个表可以记录512个物理页的位置信息。因此我们继续看如何进行初始化:

 

依然是一个循环,循环当前的表所有的Entry,调用初始化物理页信息。

 

首先通过函数找到对应的映射表的页表项的地址。通过函数

最后通过函数,将组合后的的Entry的值写入到对应的表项中。由此,页表的建立的主要流程已经完成。下面通过一个例子,系统是如何利用页表对一个虚拟地址进行寻址的:

这里以虚拟地址为例,二进制为:

1111111111111111000000000000000101000000111000001001000000000000

值是,十进制值是,因此。

值是,十进制值是,因此。

值是,十进制值是,因此。

值是,十进制是,因此。

它索引方式,如下图所。

  1. 根据得到的值,然后在表()找到对应的表项(蓝色部分),表项记录的数据是下一级表的头地址。
  2. 根据得到了的值,以及上一步获得的表的头地址,可以获取到访问到表对应的表项(绿色部分),表项记录的数据是下一级表的头地址。
  3. 根据得到了的值,以及上一步获得的表的头地址,可以获取到访问到表对应的表项(棕黄部分),表项记录的数据是下一级表的头地址。
  4. 根据得到了的值,以及上一步获得的表的头地址,可以获取到访问到表对应的表项(红色部分),表项记录的数据是物理页的地址,以及保护信息。
  5. 获得了的Entry信息后,首先通过位操作,分别得到该物理页的保护信息,以及物理地址信息。如果保护信息允许访问,那么根据物理地址信息访问物理内存,然后返回数据。
    以上就是本篇文章【内存管理源码分析-内核页表的创建以及索引方式(基于ARM64以及4级页表)】的全部内容了,欢迎阅览 ! 文章地址:http://fswenzheng.xhstdz.com/quote/85601.html 
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 物流园资讯移动站 http://fswenzheng.xhstdz.com/mobile/ , 查看更多   
发表评论
0评