虚拟地址到物理地址的映射(二)

虚拟内存到物理内存的推导

本文只介绍最普遍的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给的信息对应上。

在得到页面的基地址0x2940000后,再加上该变量在页内的偏移量之后0xf1c,得到该变量的物理地址2940f1c。

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

4)heap-addr:0x11226f0

最后,我们在看一下堆内变量0x11226f0,先转换成二进制:

获取索引:

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

在得到页面的基地址28b9000后,再加上该变量在页内的偏移量之后0x6f0,得到该变量的物理地址28b96f0。

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

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

与代码中赋值相符。

内存映射

我们在查阅内存映射关系的资料的时候,通常会找到一个这样一个图:

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

总结

总结起来,一个变量的寻址过程就是,在编译或运行时被分配虚拟地址和物理内存,内核为该虚拟地址和物理内存的地址以该进程的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来优化地址转换的效率,这个不在本文讨论的范围内。

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

我们大多从一开始学习linux就听说了虚拟内存的概念,从32位系统就知道了三级页表,到64位的四级页表,但我并没有真真切切的在内存中看到这些页表的存在和它里面的内容,直到做了jeff老师的这个实验,通过dump_guest_memory获取内存,通过crash分析内存,根据拆分虚拟地址,获取每一级页表的索引,最终找到对应的物理内存。这个实践的过程让我对linux页表有了更好的理解,希望也能帮助到有同样困惑的朋友。

以上测试用例,分析方法,均来自jeff老师的内存管理课程,具体情况见以下链接:jeff老师的内存课程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/142501.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

参与抖音官方活动:开启抖音小店的曝光与销售新机会

抖音官方活动是指由抖音平台官方组织或合作举办的各类促销活动、品牌推广活动等。参与抖音官方活动对于抖音小店来说,是一个重要的机会,可以帮助店铺获得更多的曝光和销售机会。下面四川不若与众将介绍抖音小店如何参与抖音官方活动的一般步骤和注意事项…

如何解决跨浏览器兼容性问题?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 解决跨浏览器兼容性问题⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量…

EfficientFormer:高效低延迟的Vision Transformers

我们都知道Transformers相对于CNN的架构效率并不高,这导致在一些边缘设备进行推理时延迟会很高,所以这次介绍的论文EfficientFormer号称在准确率不降低的同时可以达到MobileNet的推理速度。 Transformers能否在获得高性能的同时,跑得和Mobile…

Spring MVC 和 Spring Boot 的区别

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

向量数据库库Milvus Cloud2.3 的QA问题

1. Milvus 从 2.2.x 升级至 2.3.x 的最大变化是什么? 如果用一句话来总结,那就是使用的场景更加丰富了。具体可以从两个方面来体现,即部署环境和用户的使用感。 例如,从部署环境来看,Milvus 原来只支持 X86 架构的 CPU,版本升级后,不仅可以支持 GPU,还能够支持 ARM 架构…

十五、异常(2)

本章概要 自定义异常 异常与记录日志 异常声明 自定义异常 不必拘泥于 Java 已有的异常类型。Java异常体系不可能预见你将报告的所有错误,所以你可以创建自己的异常类,来表示你的程序中可能遇到的问题。 要自己定义异常类,必须从已有的异…

HTML详细基础(二)文件路径

目录 一.相对路径 二.绝对路径 三.超链接标签 四.锚点链接 首先,扩展一些HTML执行的原理: htmL(hypertext markup Language) 是一种规范(或者说是一种标准),它通过标记符(tag)来标记要显示…

奇舞周刊第507期:通过 View Transition API 在状态之间添加丰富的过渡动画

记得点击文章末尾的“ 阅读原文 ”查看哟~ 下面先一起看下本期周刊 摘要 吧~ 奇舞推荐 ■ ■ ■ 通过 View Transition API 在状态之间添加丰富的过渡动画 W3C 2023 年度全球技术大会 (TPAC2023) 于今年9月 11 - 15 日召开。W3C CSS 工作组成员 Bramus Van Damme(Google) 为本届…

SpringBoot集成easypoi实现execl导出

<!--easypoi依赖&#xff0c;excel导入导出--><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.4.0</version></dependency>通过Exce注解设置标头名字和单…

Linux工具(二)

前言&#xff1a;在Linux工具&#xff08;一&#xff09;中&#xff0c;我们学习了yum软件安装工具和vim文本编辑器工具&#xff0c;那么本次我们就再来介绍两种工具&#xff0c;分别是&#xff0c;编辑器gcc/g、项目自动化构建工具-make/Makefile &#xff0c;接着我们再来写一…

React的高阶函数

1.认识高阶函数 高阶组件 本身不是一个组件&#xff0c;而是一个函数函数的参数是一个组件&#xff0c;返回值也是一个组件 高阶组件的定义 import ThemeContext from "../context/theme_context"function withTheme(OriginComponent) {return (props) > {retur…

python安全工具开发笔记(六)——Python爬虫BeautifulSoup模块的介绍

一、Python爬虫基础知识介绍 1.1 Python相关库 1、requests、re 2、BeautifulSoup 3、hackhttp 1.2 Python BeautifulSoup Python BeautifulSoup模块的使用介绍∶ 1、解析内容 from bs4 import BeautifulSoup soup BeautifulSoup(html_doc) 2、浏览数据 soup.title soup…

vue 实现数字验证码功能

需求&#xff1a;写了一个 手机发送验证码后 输入固定验证码的功能 封装成一个组件,如下: <template><div class"conts"><div class"box"><div class"code_list"><div :class"[ code_item, hideIndex 0 ? co…

mysql超级聚合with rollup

超级聚合&#xff0c;是在group by的基础上&#xff0c;再次进行聚合。 它再次聚合的列&#xff0c;是select中没有用到聚合函数的列。 文章目录 例子1解释例子2表以及数据 例子1 mysql> SELECT year, country, product, SUM(profit) AS profitFROM salesGROUP BY year, c…

Vue+ElementUI实现动态树和表格数据的分页模糊查询

目录 前言 一、动态树的实现 1.数据表 2.编写后端controller层 3.定义前端发送请求路径 4.前端左侧动态树的编写 4.1.发送请求获取数据 4.2.遍历左侧菜单 5.实现左侧菜单点击展示右边内容 5.1.定义组件 5.2.定义组件与路由的对应关系 5.3.渲染组件内容 5.4.通过动态…

PHP8中伪变量“$this->”和操作符“::”的使用-PHP8知识详解

对象不仅可以调用自己的变量和方法&#xff0c;也可以调用类中的变量和方法。PHP8通过伪变量“$this->”和操作符“::”来实现这些功能。 1.伪变量“$this->” 在通过对象名->方法调用对象的方法时&#xff0c;如果不知道对象的名称&#xff0c;而又想调用类中的方法…

zabbix实现钉钉报警

首先钉钉创建一个团队 自定义关键词 查看zabbix-server脚本存放的位置&#xff1a; [rootcontrolnode ~]# grep ^AlertScriptsPath /etc/zabbix/zabbix_server.conf AlertScriptsPath/usr/lib/zabbix/alertscripts zabbix server设置 在配置文件书写脚本目录vim /etc/za…

威胁追踪如何增强您的网络安全态势

网络威胁的复杂性、频率和影响正在加剧。2022 年&#xff0c;勒索软件攻击达到2.361 亿次&#xff0c;其中 39% 的英国企业遭受网络攻击。 这些攻击需要工具和资源来识别和纠正漏洞&#xff0c;以在云环境中维护强大的安全框架&#xff0c;从而降低数据泄露和合规违规的风险。…

ptmalloc源码分析 - realloc()函数的实现(11)

目录 一、步骤1-判断边界情况&#xff0c;realloc也可以执行malloc和free的功能 二、步骤2-原chunk如果MMAP方式分配&#xff0c;申请新内存并拷贝实现 三、步骤3-非MMAP方式分配&#xff0c;则_int_realloc进行合并/裁剪等实现 1. _int_realloc函数&#xff1a;老chunk足够…

系统化思考,从初级到高级书单推荐

用思考工具进行系统思考&#xff0c;解决复杂问题&#xff0c;成为某个领域的高手&#xff0c;下面这几本书就是补充你脑海的系统思考的工具&#xff0c;一定要保存。 《简单的逻辑学》 作者&#xff1a;麦克伦尼 一切的系统源自于逻辑&#xff0c;如果你没有逻辑分析的能力&…