MMU如何通过虚拟地址找到物理地址-下

2023-10-14 17:15

本文主要是介绍MMU如何通过虚拟地址找到物理地址-下,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

接着上文:MMU如何通过虚拟地址找到物理地址?

5,虚拟内存到物理内存的推导 本文只介绍最普遍的64位地址,四级页表,每个页表4k的这种情况。

linux内核将一个进程的内存映射表建立好之后,在该进程被调度运行的时候,会将PGD的物理地址放置到MMU的页表基地址寄存器中,在X86_64架构下,该寄存器为CR3,ARM64架构下,该寄存器为ttbr0_el1和ttbr1_el1,接下来的寻址过程中,就不需要linux来干预了,MMU会通过PGD-PUD-PMD-PTE-PAGE-OFFSET这个过程,根据虚拟地址,找到其对应的物理地址。那么这个过程是怎样的呢?

1)我们首先来拆分一下虚拟地址,以“filemap-addr:0x7fc3d3e4c000为例”,0x7fc3d3e4c000被分为5个部分,其中  0-11bit为页内偏移地址,根据页基地址+偏移量找到对应的物理内存; 12-20bit为PTE的索引,该索引可以找到物理内存页面的基地址; 21-29bit为PMD的索引,该索引可以找到PTE的页基地址; 30-38bit为PUG的索引,该索引可以找到PMD的页基地址; 39-47bit为PGD的索引,该索引可以找到PUD的页基地址。首先我们使用命令bc来得到0x7fc3d3e4c000的二进制:

我们将该地址按上述规则拆分一下:PGD索引:11111111,需要左移12bit,得到11111111000,即0x7f8 PUD索引:100001111,需要左移12bit,得到100001111000,即0x878 PMD索引:010011111,需要左移12bit,得到010011111000,0x4f8 PTE索引:001001100,需要左移12bit,得到001001100000,即0x260

注意,PGD,PUD.PMD,PTE的索引都要左移12bit,可以看出来PGD的索引7f8,pud的索引878,PMD的索引4f8,PTE的索引260,都能和vtop给的信息对应上。

我们再使用rd命令直接从内存中读取信息看一下:

从这个过程中,我们可以看到MMU有两个数据信息,即PGD的基地址47de000和虚拟地址0x7fc3d3e4c000,MMU通过PGD+0x7f8找到PUD的地址5f7c000,通过PUD+878得到PMD的地址0x5f66000,通过PMD+4f8得到PTE的地址0x5f64000,通过PTE+260得到物理页面的地址28ba000,本例没有页内偏移量,索引0x7fc3d3e4c000对应的物理地址就是28ba000。2)g-addr:0x4c82f0 转换成二进制

获取索引:

可以看出PGD和PUD的索引为0,PMD索引为0x10,PTE的索引为0x640,都能和vtop给的信息对应上。

在得到页面的基地址0x1f4ed000后,再加上该变量在页内的偏移量之后0x2f0,得到该变量的物理地址0x1f4ed2f0。使用rd命令直接从内存中读取信息看一下

最后再看一下该变量的值:

与代码中赋值相同。

3)stack-addr:0x7ffe03a8ef1c 转换成二进制

获取索引

可以看出来PGD的索引7f8,pud的索引fc0,PMD的索引0e8,PTE的索引470,都能和vtop给的信息对应上。

 资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linuxc/c++高级开发【直播公开课】

零声白金VIP体验卡:零声白金VIP体验卡(含基础架构/高性能存储/golang/QT/音视频/Linux内核)

在得到页面的基地址0x2940000后,再加上该变量在页内的偏移量之后0xf1c,得到该变量的物理地址2940f1c。使用rd命令直接从内存中读取信息看一下:

4)heap-addr:0x11226f0 最后,我们再看一下堆内变量0x11226f0,先转换成二进制:

获取索引:

可以看出PGD和PUD的索引为0,PMD索引为0x40,PTE的索引为0x910,都能和vtop给的信息对应上。

在得到页面的基地址28b9000后,再加上该变量在页内的偏移量之后0x6f0,得到该变量的物理地址28b96f0。使用rd命令直接从内存中读取信息看一下

最后再看一下物理内存中的值:

与代码中赋值相符。6,内存映射 我们在查阅内存映射关系的资料的时候,通常会找到一个这样一个图:

这个图很清楚的表示了PGD,PUD,PMD和PTE的关系,下面我们把本例中涉及到的地址数据填充进去,效果看起来会更直观和清晰。

7,总结

总结起来,一个变量的寻址过程就是,在编译或运行时被分配虚拟地址和物理内存,内核为该虚拟地址和物理内存的地址以该进程的PGD表为基础,建立映射关系,并将PGD的物理地址交给MMU,MMU根据映射关系通过虚拟地址找到物理地址,并按照程序的要求读写其中的内容。

1)编译和链接 在本例中有四种类型的变量: filemap-addr:0x7fc3d3e4c000 内存映射文件虚拟地址  g-addr:0x4c82f0 全局变量虚拟地址  stack-addr:0x7ffe03a8ef1c 栈内变量虚拟地址  heap-addr:0x11226f0 堆内变量虚拟地址 其中内存映射文件的虚拟地址是内核执行mmap的时候分配的,栈和堆都是在进程创建的时候分配的物理内存并指定了虚拟内存地址,栈内变量和堆内变量的虚拟地址就是堆栈的虚拟地址加上偏移量获得。全局变量的地址是在编译链接的过程中指定的,本例的全局变量没有初始化,所以放在a.out的bss区,bss区的起始虚拟地址为00000000004c82a0:

全局变量g的虚拟地址为:

2)内存页表的建立 在进程创建的时候,内核会为a.out的每个section分配物理内存,堆栈也要分配物理内存,同时根据为进程创建物理内存和虚拟内存的映射关系。最后,把PGD的物理地址放到MMU的页表基地址寄存器中,剩下的事儿交给MMU。可以理解为从虚拟内存到物理内存的转换的逆过程。

3)MMU进行地址转换 从虚拟内存到物理内存的转换是mmu通过页表映射来实现的,无需操作系统干预,本文所讲的寻址过程是最基础的虚拟地址到物理地址的转换过程,但MMU还会利用tlb来优化地址转换的效率,这个不在本文讨论的范围内。

8,其他 本文只介绍了最简单的4级页表,4k页面的映射关系和寻址过程,其实,内核的内存管理还有更复杂的映射,比如使用5级页表,或者每个映射单位为2M或1G的内存块,这些映射方法的索引级数和各级索引所占的bit位都有所不同。

原文作者:Jeff Labs

这篇关于MMU如何通过虚拟地址找到物理地址-下的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/211946

相关文章

在二叉树中找到两个节点的最近公共祖先(基于Java)

如题  题解 public int lowestCommonAncestor(TreeNode root, int o1, int o2) {//记录遍历到的每个节点的父节点。Map<Integer, Integer> parent = new HashMap<>();Queue<TreeNode> queue = new LinkedList<>();parent.put(roo

两个月冲刺软考——逻辑地址与物理地址的转换(例题+讲解);文件类型的考点

1.已知计算机系统页面大小和进程的逻辑地址,根据页面变换表(页号-物理块号),求变换后的物理地址。 首先介绍几个公式: 逻辑地址 = 页号 + 页内地址 (默认为32机位) 物理地址 = 物理块号 + 物理地址的页内地址 其中:页内地址 = 物理地址的页内地址 解题:由于页面大小为4K,即4K=2的12次方,占0~11位;也就是页内地址有12位,故十六进制数中的C28是页内地址,那

ARM架构(五)——MMU①

1.MMU基础 1.1 为什么要用MMU,为什么要用虚拟地址? MMU的作用,主要是完成地址的翻译,即虚拟地址到物理地址的转换,无论是main-memory地址(DDR地址),还是IO地址(设备device地址),在开启了MMU的系统中,CPU发起的指令读取、数据读写都是虚拟地址,在ARM Core内部,会先经过MMU将该虚拟地址自动转换成物理地址,然后在将物理地址发送到AXI总线上,完成真正

Spring是如何找到URL请求对应的Controller的

文章来源 原文作者:Spring MVC 原文地址: https://blog.csdn.net/hl233211/article/details/77450697 http://ddrv.cn/a/58528 本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。 序:先贴一张SpringMVC整体的框架原理图 此文主要描述Spring在响应请求的时候是如何根据U

LeetCode438. 找到字符串中所有字母异位词(2024秋季每日一题 11)

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。 示例 1: 输入: s = “cbaebabacd”, p = “abc” 输出: [0,6] 解释: 起始索引等于 0 的子串是 “cba”, 它是 “abc” 的异位词。 起始索引等于 6 的子串是

涨幅超过了90%,心动网络股价成V字后,TapTap找到流量源了吗?

心动公司发布了截至2024年6月30日止六个月的中期业绩。 在2024年上半年(24H1),公司实现总营收22.21亿元,较去年同期增长了26.7%。归属于母公司的净利润达到2.05亿元,同比激增127.4%。经调整后,归属于母公司的净利润更是攀升至2.37亿元,同比增长率高达110.0%。 与业绩对应的是股价变化。 自2024年初以来,在港股市场近30只游戏软件相关股票

关于win7下Django无法找到manage.py

前一段时间学习Python-Django,由于目前对Linux还不是很熟悉所以就在window下学习了,用的是Python3.3在建立个人blog时就是找不到Django生成的文件,可是也不显示出错,在网上找了很多说是bug经过认真仔细观察终于发现了在电脑C盘用户本机里面,现在写出来希望有需要的不要再浪费精力了

进程的那些事——了解进程(虚拟地址空间)

目录 前言 一、程序地址空间(虚拟地址空间) 二、虚拟地址寻找物理内存 1.页表 总结 前言 提示:这里可以添加本文要记录的大概内容: 程序和进程之间的区别:         进程:对用户而言,进程是运行中的程序,但实际是进程是对程序动态运行的描述。当程序被加载到内存中并由操作系统执行就变成了进程。进程有独立的内存空间。它的生命周期到进程结束或操作系统终止。

【算法:二分查找】java算法二分查找,如何通过二分查找找到重复元素的第一个,coding

二分查找算法,是基于有序的结果集进行查询的 二分查找的时间复杂度是O(logN) 写一段二分查询的代码: public static void main(String[] args) {int[] data = new int[]{1, 2, 3, 3, 5, 5, 6, 8, 9, 9, 10};int queryData = 5;int index = queryDataIndex(qu

【游戏安全】CheatEngine基础使用——如何对不同类型的数值进行搜索?如何破解数值加密找到想修改的数值?

游戏安全 不同数值类型的搜索破解简单数值加密 不同数值类型的搜索 可以在游戏中看到很精确的物品数量,但是在CE中却什么都扫不到。 这是因为他的数值类型可能并不是四字节的,在游戏中这个数值的机制是一个慢慢增长的数值,所以他很有可能是浮点数,增长0.几,满1再加1显示,但是隐去了小数点后的数字,所以要更换数值类型再进行扫描测试。 将单浮点数和双浮点数都测试一下。 更换为单浮点数