ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【ARM-MMU】ARMv8-A 的虚拟地址向物理地址转换的过程

2019-03-01 16:48:25  阅读:734  来源: 互联网

标签:转换 MMU 程序 虚拟地址 物理地址 地址 内存 Entry 内存地址


为什么使用虚拟地址

在早期的计算机中,要运行一个程序,会把这些程序全都装入内存,程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址。在早期的计算机中,要运行一个程序,会把这些程序全都装入内存,程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址。

当计算机同时运行多个程序时,必须保证这些程序用到的内存总量要小于计算机实际物理内存的大小。那当程序同时运行多个程序时,操作系统是如何为这些程序分配内存的呢?下面通过实例来说明当时的内存分配方法:

某台计算机总的内存大小是128M,现在同时运行两个程序A和B,A需占用内存10M,B需占用内存110。计算机在给程序分配内存时会采取这样的方法:先将内存中的前10M分配给程序A,接着再从内存中剩余的118M中划分出110M分配给程序B。这种分配方法可以保证程序A和程序B都能运行,但是这种简单的内存分配策略问题很多:

问题1:进程地址空间不隔离。由于程序都是直接访问物理内存,所以恶意程序可以随意修改别的进程的内存数据,以达到破坏的目的。有些非恶意的,但是有bug的程序也可能不小心修改了其它程序的内存数据,就会导致其它程序的运行出现异常。这种情况对用户来说是无法容忍的,因为用户希望使用计算机的时候,其中一个任务失败了,至少不能影响其它的任务。

问题2:内存使用效率低。在A和B都运行的情况下,如果用户又运行了程序C,而程序C需要20M大小的内存才能运行,而此时系统只剩下8M的空间可供使用,所以此时系统必须在已运行的程序中选择一个将该程序的数据暂时拷贝到硬盘上,释放出部分空间来供程序C使用,然后再将程序C的数据全部装入内存中运行。可以想象得到,在这个过程中,有大量的数据在装入装出,导致效率十分低下。

问题3:程序运行的地址不确定。当内存中的剩余空间可以满足程序C的要求后,操作系统会在剩余空间中随机分配一段连续的20M大小的空间给程序C使用,因为是随机分配的,所以程序运行的地址是不确定的。

为了解决上述问题,人们想到了一种变通的方法,就是增加一个中间层,利用一种间接的地址访问方法访问物理内存。按照这种方法,程序中访问的内存地址不再是实际的物理内存地址,而是一个虚拟地址,然后由操作系统将这个虚拟地址映射到适当的物理内存地址上。这样,只要操作系统处理好虚拟地址到物理内存地址的映射,就可以保证不同的程序最终访问的内存地址位于不同的区域,彼此没有重叠,就可以达到内存地址空间隔离的效果。

ARMv8的四级页表的转换

地址转换
虚拟地址向物理地址转换的有专门的空间来存放转换的Descriptor。
ARMv8 的虚拟地址的寻址范围是48 bit。对于地址范围位于0x00000000_00000000 ~ 0x0000FFFF_FFFFFFFF之间的,要在寄存器TTBR0_EL1(Translation Table Base Register 0, 限于EL0和EL1) 寻找转换表的基址。对于地址范围位于0xFFFFFFFF_FFFFFFFF ~ 0x0000FFFF_FFFFFFFF之间的,要在寄存器TTBR1_EL1(限于EL0和EL1) 寻找转换表的基址。

具体是怎么转换的呢:

以4K页表的4级转换为例,展示虚拟地址向物理地址的转换过程:

4K 页表 4级转换方式
如上图所示,步骤如下:

1.首先查看Virtual Address 的高16位VA[63:48]是否为全0,如果全0,使用TTBR0_EL1寄存内放的Level 0 Page Table的基地址; 否则,使用TTBR1_EL1.
在这里插入图片描述
2.由于是4K的页表,4K页表的大小是这样的计算的: 4KB = 1024 × 8 × 4 = 512 × 64 bit. 就是说4K 的页表要分为512个Entry, 每个Entry的大小为64bit。每个Entry存放的数据,实际是下一个level 的转换表的地址。对于某个VA[47:0], 我们怎么知道下一级页表的地址存放在这512个 Entry 中的那个Entry呢?答案是使用VA[47:39]来索引。这样就可以找到第二级转换表(level 1 page table)的首地址.

3.同样,Level 1 page table 也是4K 共512 个Entry,每个Entry 存放下一个页表的首地址,这个首地址的存放的位置要用VA[38:30]去索引Level 1 page table的Entry 得到. 样就可以找到第三级转换表(level 2 page table)的首地址.
在这里插入图片描述
4.同样,Level 2 page table 也是4K 共512 个Entry,每个Entry 存放下一个页表的首地址,这个首地址的存放的位置要用VA[29:21]去索引Level 1 page table的Entry 得到. 样就可以找到第四级转换表(level 3 page table)的首地址.

5.Level 3 page table 内存放的就是VA 向 PA转换的Descriptor了, 也是512个entry,每个Entry 64bit的数据。 通过VA[20:12]来索引使用那个Entry的descriptor。在这个descriptor中就可以得到我们想要的物理地址的 PA[47:12].
在这里插入图片描述
6.最终的地址转换完成,VA[47:0] 转换为 PA[47:0] = {来自level 3 转换表的PA[47:12], VA[11:0]}. 就是Descriptor 中给出物理地址的[47:12], 而虚拟地址给出物理的值的[11:0].

标签:转换,MMU,程序,虚拟地址,物理地址,地址,内存,Entry,内存地址
来源: https://blog.csdn.net/liujingyu_1205/article/details/88062712

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有