1. 页表转换寄存器描述符

1.1,页表/页目录结构

基于前言中的内核配置,内核采用39位虚拟地址,因此可寻址范围为2^39 = 512G,采用(linux 默认为五级页表,另外还有PUD,P4D,由于本文只配置三级,其他两项不予罗列)3级页表结构,分别为:

    PGD   (Page Global Directory)                    bit[39:30]      level1

    PMD   (Page Middle Directory)                    bit[30:21]     level2

    PTE    (Page Table)                              bit[21:12]      level3

每一级索引占9bit,也就是每一个页目录表/页表都有29=512个页目录项/页表项,使用4k页面大小,212 = 4096,因此虚拟地址中offset字段占12位,每一个pte页表项可以映射4k个地址空间,共有512x512x512个pte页表项,总的可寻址地址空间为 512x512x512x4096 = 2^39 = 512Gb。

每一个页表项占用8个字节,每一张页表有512项,所以一张页表占用空间为512*8=4K,因此页表的基地址都是4k对齐的,也就是页表基地址的低12位都为0;

内核页表相关重要宏控,相信你仔细看过第三节的实例之后,对这些宏控都会有清晰得理解!!

pgd_offset(mm,addr)          ---接受内存描述符mm,和一个虚拟地址作为参数,这个宏产生addr在页全局目录在相应表项中的线性地址
pgd_offset_k(addr) ---用来产生内核页全局目录在相应表项中的线性地址
pgd_index(addr) ---从addr中提取页全局目录表项的索引 pmd_index(addr) ---从addr中提取页中间目录表项的索引
pmd_offset(pud,addr) ---接受页上级目录指针,和虚拟地址作为参数,这个宏产生目录项addr在页中间目录项中的偏移地址 pte_index(addr) ---从addr中提取页中间目录表项的索引
pge_offset_kernel(dir,addr) ---线性地址addr在页中间目录dir中有一个对应项,该宏就产生这个对应项,即页表的线性地址

2. 转换相关寄存器描述符

2.1 转换基址寄存器

TTBR1 :(Translation Table Base Register)转换表基地址寄存器,用来存放内核(init_mm.pgd)PGD全局转换表的基地址;

TTBR0 :(Translation Table Base Register)转换表基地址寄存器,用来存放用户(task_struct.mm.pgd)PGD全局转换表的基地址;

2.2 转换描述符格式

armv8规定,所有页级别都是用同一个描述符格式,PGD只能输出下一级目录表的基地址。PTE描述符不能指向另一个表的基地址,只能输出块地址。那么反过来PMD,PUD是可以直接输出地址块的,也就是直接指向一个块地址,下一级页表就不会再被映射,这种情况我们称之为巨页,

pte 映射   页大小=4k    2^12

pmd 映射 页大小=2m    2^(12+9)

pud映射  页大小=1G     2^(12+9+9)

如上图是一个48bit地址的例子,可以看出来,其D_Block在各个页表中的映射块大小,也可以在附录2 表的第三列看到这种情况,这里我们的描述以实例只针对pte的映射,也就是页大小4k。

所有页目录/页表项描述符由低bit[1:0]位指出,有以下三种情况:

a,下一级表的地址,在这种情况下,内存可以进一步细分为更小的块(页表级数越多,pte映射的页大小就越小)。

b,可变大小的内存块的地址(如果为块地址,其还需要加上va[offset]才能构成物理地址,所以称可变大小)。

c,可以标记为Fault或Invalid(无效条目)。

当bit[1:0]={0,1}时,为block entry ,其中间部分为物理地址的高位PA[39:12] ;

当bit[1:0]={1,1}时, 为table entry,其中间部分[39:12]为下一级页表的物理基地址;

当bit[1:0] = {1,0|0,0}时,该表项为无效项;

转换表描述符中lower attributes中存储相关属性信息,mmu在查找到相应的表项时,首先会查询属性信息,确认地址的相关属性(可执行权限,访问权限,共享属性,访问标志,安全标志等)后,根据需要取出下一级页表的基地址。

2.3 用户/内核PGD表基地址

基于之前的分析可知,用户虚拟地址和内核虚拟地址转换为物理地址的时候使用不同的页表基地址寄存器(TTBRx),因此他们的转换是基于不同的全局页目录表PGD。

其中内核全局页目录表PGD存储在init_mm.pgd中,我们知道内核是常驻内存的,因此内核的PGD表只有一份,他不会因为进程的切换而改变,所有内核地址访问都依赖这一个PGD表;用户全局页目录表PGD存储在进程描述符task_struct.mm.pgd中,他是在用户进程被创建时同步被创建的,每一个进程描述符task_struct都对应有自己的task_struct.mm.pgd表,进程所有地址的访问都依赖于对应的task_struct.mm.pgd页表的查询,因此在进程切换时,TTBR0中的值(task_struct.mm.pgd)是要同时改变的,这也与linux中每一个进程都独占整个虚拟(此为512G)地址空间相对应;

三、转换流程

据此可以画出如下转换框图:

MMU在转换虚拟地址的时候遵循以下步骤(基于以上配置):

1,如果虚拟地址bit[63:40]都为1,则使用TTBR1作为第一级页目录表基地址,当bit[63:40]都为0时,使用TTBR0作为第一级页目录表基地址;

2,PGD包含512个64位PMD表,从虚拟地址中获取VA[39:31]进行索引,找到对应条目为PGD+index[39:31]);

4,MMU检查PGD目录项的有效性(bit[1:0]),以及其属性标志判断是否允许请求的内存访问。假设它有效,且允许访问内存;

5,MMU从PGD目录表项中获取bit[39:12],作为PMD页表的物理基址(table descriptor)。

6,PMD包含512个64位PTE表,从虚拟地址中获取VA[30:21]进行索引,PMD+(index[30:21]8),MMU从PMD表项中读取PTE表的基地址;

7,MMU检查PMD目录项的有效性(bit[1:0]),以及其属性标志判断是否允许请求的内存访问。假设它有效,且允许访问内存;

8,pmd目录表项中获取bit[39:12],作为pte页表的物理基基址,

9,pte指向一个4k的页(page descriptor),mmu获取pte的bit[39:12]作为最终物理地址的pa[39:12];

10,取出va[11:0]作为pa[11:0],然后返回完整的PA[39:0],以及来自页表项的附加信息。

基于4K page大小的一个完整的转换过程,如下图 ​​​​:

深入理解虚拟 物理地址转换,页表--基于ARMV8的更多相关文章

  1. 基于ARMv8的固件系统体系结构

    基于ARMv8的固件系统体系结构 The architecture of ARMv8-based firmware systems 自2011年发布以来,ARMv8处理器架构在移动设备市场上已经相当普 ...

  2. 服务器端打开office然后采用虚拟打印 转换成pdf

    服务器端打开office然后采用虚拟打印 转换成pdf [WebMethod] public bool ConvertWordTOPDF(string WordPath) { bool ret=fal ...

  3. 全面理解虚拟DOM(1)

    最近一两年前端最火的技术莫过于 reactjs,angularJS,vuejs,即便你没用过也可能听过,像ReactJS由业界顶尖的互联网公司facebook提出,其本身有很多先进的设计思路,比如页面 ...

  4. 全面理解虚拟DOM,实现虚拟DOM

    1.为什么需要虚拟DOM DOM是很慢的,其元素非常庞大,页面的性能问题鲜有由JS引起的,大部分都是由DOM操作引起的.如果对前端工作进行抽象的话,主要就是维护状态和更新视图:而更新视图和维护状态都需 ...

  5. 理解虚拟主机与VPS,云服务器CVM与云服务器ECS的区别

    1.理解虚拟主机与VPS的区别:VPS与虚拟主机的区别 2.理解云服务器CVM与云服务器ECS的区别:云服务器CVM与云服务器ECS的区别 3.锐速安装一键包

  6. Linux 内核虚拟地址到物理地址转换讨论【转】

    转自:https://blog.csdn.net/sunlei0625/article/details/59476987 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请 ...

  7. 深入理解Struts2----类型转换

         之前的一系列文章主要介绍了有关Struts2的一些基本用法和部分的简单原理,但是始终没有介绍有关拦截器的相关内容,从本篇开始我们将从另一个角度去深入理解框架的使用,核心还是拦截器,但本篇首先 ...

  8. 怎么理解虚拟 DOM?

    一.前言 现在web前端的开发,对于MVVM框架的运用,那是信手拈来,用的飞起.一个xxx-cli工具,就能初始化一套模板,再填充业务代码,打包部署即可.但是会用,是一个方面,大家有没有底层深入思考一 ...

  9. 【解答】关于内核中没开MMU之前的虚拟地址物理地址转换问题

    1. 内核没开MMU之前有虚拟地址吗?没有MMU哪来的虚拟地址? 答:有,由于载入时地址和执行时地址不同导致的没打开MMU之前也会有虚实地址问题. 2. 载入时地址和执行时地址什么差别.为什么有这样的 ...

  10. 理解及操作环境变量(基于Mac操作)

    通过本文,简单的了解下环境变量及其操作,与便于遇到相关问题时能够准确快捷的解决. 什么是环境变量 An environment variable is a dynamic-named value th ...

随机推荐

  1. hive导入mysql

    hive测试--HIVE数据分析02 题目: 4.处理结果入库:(在虚拟机安装mysql)    将上述统计分析的结果数据保存到mySQL数据库中. #text3_1入库 #1.添加驱动,在hive的 ...

  2. 对比python学julia(第四章:人工智能)--(第二节)人脸识别

    2.1.  项目简介 人脸识别是基于人的脸部特征信息进行身份识别的一种图像识别技术.使用0PenCV 进行人脸识别的过程如下. (1)  针对每个识别对象收集大量的人脸图傣作为样本. (2)  将样本 ...

  3. 【Java-GUI】03 事件监听

    --1.监听机制案例 简答理解:操作驱动程序执行 完整的操作体系:事件源.事件.监听器.注册监听 案例: 点击OK按钮,让上方的输入框写入一段字符 package cn.dzz; import jav ...

  4. 【Docker】01 概述

    什么是Docker? 一个开源的应用容器引擎 由Go语言开发而成,遵循Apache2.0开源协议 允许开发者打包自己的应用或者依赖包组件到一个轻量级可移植的容器中 Docker容器采用沙箱机制,相互之 ...

  5. 何时使用交叉熵,何时使用KL散度:计算分布差距为啥使用KL散度而不用交叉熵,计算预测差距时为啥使用交叉熵而不用KL散度

    问题: 何时使用交叉熵,何时使用KL散度? 计算分布差距为啥使用KL散度而不用交叉熵,计算预测差距时为啥使用交叉熵而不用KL散度 问题很大,答案却很简单. 答案: 熵是一种量度,是信息不确定性的量度: ...

  6. .NET 高效开发Nuget管理工具(开源)

    我们.NET开发会引用很多外部Nuget包,多项目.多个解决方案.甚至多个仓库. 简单的Nuget包管理,通过VS就能比较简单处理好.但复杂的场景呢,比如: 1.一个仓库里,有多个解决方案的Nuget ...

  7. 【CMake系列】01-CMake是什么

    在很多开源项目中,经常可以看到CMakeLists.txt 这一文件,依靠它才能完成项目的配置运行过程.那它是什么? 接下来,在这个专栏中,我们将系统学习CMake这一个重要工具. 本专栏的实践代码全 ...

  8. JavaScript设计模式样例八 —— 适配器模式

    适配器模式(Adapter Pattern) 定义:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作.目的:主要解决在软件系统中,常常要将一些&quo ...

  9. C# 导出datatable数据到excel

    第一步:下载两个需要的NUGET包 1.org.in2bits.MyXls:2.NPOI 第二步:关键类OutExcel. using System; using System.Linq; using ...

  10. 根据Uri,Cursor没有获取到对应的属性

    Android: 背景:调用摄像头,拍摄视频,指定保存的地址,但是返回的Cursor文件,只有名称和大小的属性,没有其他诸如时长,连ID属性都没有 使用 cursor.getInt(cursor.ge ...