用户态内存映射

news2024/11/29 11:47:08

内存映射不仅仅是物理内存和虚拟内存之间的映射,还包括将文件中的内容映射到虚拟内存空间。这个时候,访问内存空间就能够访问到文件里面的数据。而仅有物理内存和虚拟内存的映射,是一种特殊情况。

对于堆的申请来讲,mmap 是映射内存空间到物理内存。

如果一个进程想映射一个文件到自己的虚拟内存空间,也要通过 mmap 系统调用。这个时候 mmap 是映射内存空间到物理内存再到文件。

如果是匿名映射,则调用 mm_struct 里面的 get_unmapped_area 函数。这个函数其实是 arch_get_unmapped_area。它会调用 find_vma_prev,在表示虚拟内存区域的 vm_area_struct 红黑树上找到相应的位置。之所以叫 prev,是说这个时候虚拟内存区域还没有建立,找到前一个 vm_area_struct。

如果不是匿名映射,而是映射到一个文件,这样在 Linux 里面,每个打开的文件都有一个 struct file 结构,里面有一个 file_operations,用来表示和这个文件相关的操作。如果是我们熟知的 ext4 文件系统,调用的是 thp_get_unmapped_area。如果我们仔细看这个函数,最终还是调用 mm_struct 里面的 get_unmapped_area 函数。殊途同归。

 PGD、P4G、PUD、PMD、PTE四级页表的概念如下:

pgd_t 用于全局页目录项,pud_t 用于上层页目录项,pmd_t 用于中间页目录项,pte_t 用于直接页表项。

一个进程的虚拟地址空间包含用户态和内核态两部分。为了从虚拟地址空间映射到物理页面,页表也分为用户地址空间的页表和内核页表,这就和上面遇到的 vmalloc 有关系了。在内核里面,映射靠内核页表,这里内核页表会拷贝一份到进程的页表。

cr3 是 CPU 的一个寄存器,它会指向当前进程的顶级 pgd。如果 CPU 的指令要访问进程的虚拟内存,它就会自动从 cr3 里面得到 pgd 在物理内存的地址,然后根据里面的页表解析虚拟内存的地址为物理内存,从而访问真正的物理内存上的数据。

这里需要注意两点。第一点,cr3 里面存放当前进程的顶级 pgd,这个是硬件的要求。cr3 里面需要存放 pgd 在物理内存的地址,不能是虚拟地址。因而 load_new_mm_cr3 里面会使用 __pa,将 mm_struct 里面的成员变量 pgd(mm_struct 里面存的都是虚拟地址)变为物理地址,才能加载到 cr3 里面去。

第二点,用户进程在运行的过程中,访问虚拟内存中的数据,会被 cr3 里面指向的页表转换为物理地址后,才在物理内存中访问数据,这个过程都是在用户态运行的,地址转换的过程无需进入内核态。

只有访问虚拟内存的时候,发现没有映射到物理内存,页表也没有创建过,才触发缺页异常。进入内核调用 do_page_fault,一直调用到 __handle_mm_fault,这才有了上面解析到这个函数的时候,我们看到的代码。既然原来没有创建过页表,那只好补上这一课。于是,__handle_mm_fault 调用 pud_alloc 和 pmd_alloc,来创建相应的页目录项,最后调用 handle_pte_fault 来创建页表项。

为了加快映射速度,我们不需要每次从虚拟地址到物理地址的转换都走一遍页表。

页表一般都很大,只能存放在内存中。操作系统每次访问内存都要折腾两步,先通过查询页表得到物理地址,然后访问该物理地址读取指令、数据。

为了提高映射速度,我们引入了 TLB(Translation Lookaside Buffer),我们经常称为快表,专门用来做地址映射的硬件设备。它不在内存中,可存储的数据比较少,但是比内存要快。所以,我们可以想象,TLB 就是页表的 Cache,其中存储了当前最可能被访问到的页表项,其内容是部分页表项的一个副本。

有了 TLB 之后,地址映射的过程就像图中画的。我们先查块表,块表中有映射关系,然后直接转换为物理地址。如果在 TLB 查不到映射关系时,才会到内存中查询页表。

此文章为11月Day5学习笔记,内容来源于极客时间《趣谈Linux操作系统》,推荐该课程。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

试试流量回放,不用人工写自动化测试case了

大家好,我是洋子,接触过接口自动化测试的同学都知道,我们一般要基于某种自动化测试框架,编写自动化case,编写自动化case的依据来源于接口文档,对照接口文档里面的请求参数进行人工添加接口自动化case 其实…

应用安全四十二:SSO安全

一、什么是SSO SSO是单点登录(Single Sign On)的缩写,是指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。这种方式减少了由登录产生的时间消耗,辅助了用户管理,是比较流行的企业业务整合的解决方案之一。 身份验证过程依赖于双方之间的信任关…

大数据毕业设计选题推荐-智慧小区大数据平台-Hadoop-Spark-Hive

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

2022年ISSCC会议报告分析

Tutorial Fundamentals of Self-Sensing Processor Systems AMD Zen架构的CCD die中有很多传感器检测die的频率、电压、电压和温度 HBM DRAM and 3D Stacked Memory Advances in Digital vs. Analog AI Accelerators Nvidia的Multi-chip架构的DNN加速器 Form1: Compute-in…

Pycharm-community-2021版安装和配置

一、下载Pycharm-community-2021 1.从官网下载pycharm-community Pycharm 版本官网 二、安装PyCharm 1.打开下载完成的安装包,点击Next 2.安装PyCharm到其他位置,点击Next 3.一定把更新PATH变量勾上,可以创建桌面快捷方式,创建关联,最后…

apache-maven-3.6.3 安装配置教程

链接:https://pan.baidu.com/s/1RkMXipnvac9EKcZyUStfGQ?pwdl32m 提取码:l32m 1. 将 maven 压缩包解压至指定文件夹 2. 配置环境变量 (1)打开此电脑-> 鼠标右键选择属性->点击高级系统设置 (2)点…

【移远QuecPython】EC800M物联网开发板的硬件PWM和PWM输出BUG

【移远QuecPython】EC800M物联网开发板的硬件PWM和PWM输出BUG 文章目录 导入库初始化PWM开启PWMPWM硬件BUG附录:列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包 导入库 from misc import PWM_V2或者 from misc import PWM但我觉得PWM_V2好用 初…

嵌入式中如何把C++代码改写成C语言代码

由于C++解释器比C语言解释器占用的存储空间要大500k左右。为了节省有限的存储空间、降低成本,同时也为了提高效率,将用C++语言写的源程序用C语言改写是很有必要的。 C++与C最大的区…

高位片选与低位交叉编址、芯片扩展与多模块存储器、多通道内存

多模块存储器 是一种空间并行技术,利用多个结构完全相同的存储模块的并行工作来增加存储器的吞吐率。根据不同的编址方式,多模块存储器分为连续编址和交叉编址两种结构 连续编址方式:主存地址的高位表示模块号(体号)…

Python--快速入门二

Python--快速入门二 1.Python数据类型 1.可以通过索引获取字符串中特定位置的字符: a "Hello" print(a[3]) 2.len函数获取字符串的长度: a "Hello" print(a) print(len(a)) 3.空值类型表示完全没有值: 若不确定当…

【嵌入式项目应用】__物联网小知识:不同通讯线的通讯距离是多少,你知道吗?

目录 前言 不同协议通讯线的传输距离 无线传输协议与距离 1. 蓝牙 2. Zigbee 3. LoRa 4. Wi-Fi 5. 蜂窝网络 6. Sigfox 7. LoRaWAN (* ̄︶ ̄)创作不易!期待你们的 点赞、收藏和评论喔。 前言 在物联网中,通讯线的作用是…

leetcode经典面试150题---5.多数元素

目录 题目描述 前置知识 代码 方法一 排序法 思路 实现 复杂度 方法二 哈希表 思路 实现 题目描述 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给…

pg14-sql基础(四)-多表联查

多表联查 内联查询 SELECT e.department_id, e.first_name, d.department_name FROM employees e INNER JOIN departments d -- JOIN departments d ON e.department_id d.department_id;左外联查询 SELECT e.department_id, e.first_name, d.department_name FROM employees…

【C语言基础】第01章_C语言入门

讲师:康师傅 视频:https://www.bilibili.com/video/BV1Bh4y1q7Nt?p1&vd_source3eaa9d17f2454e1ae80abc50d16e66b5 文章目录 本章专题脉络1初识计算机语言1.1 计算机语言是什么1.2 计算机语言简史 2初识C语言2.1 C语言的由来2.2 为什么要学习C语言2.…

英语——分享篇——每日200词——1-200

1——ball——[bɔːl]——n.球——ball——ba爸(拼音)ll筷子(象形)——爸爸用筷子夹球——The kid is playing the ball. ——孩子在玩皮球。 2——boat——[bəʊt]——n.船——boat——bo60(象形)at在(熟词)——60个人在船上——I have 60 boats.——我有60艘船。 3——bag—…

【架构图解】API架构图解:如何以图表形式展现复杂系统

文章目录 前言序列图组件图数据流程图结论 前言 架构图是链接到 API 的不同组件/服务如何相互交互的直观表示。 当需要理解 API 的架构并将其传达给不同的利益相关者(包括其他开发人员、项目经理和客户)时,这些图表非常有用。 图表/视觉效…

Python基础入门例程50-NP50 程序员节(循环语句)

最近的博文: Python基础入门例程49-NP49 字符列表的长度-CSDN博客 Python基础入门例程48-NP48 验证登录名与密码(条件语句)-CSDN博客 Python基础入门例程47-NP47 牛牛的绩点(条件语句)-CSDN博客 目录 最近的博文&a…

告知粉丝 重要

告知! 亲爱的粉丝朋友们,由于CSDN(博客)平台的限制,被迫转入 公众号!希望粉丝朋友们谅解!我们也是被逼无奈~~ 但我们还是会在CSDN(博客)发文章,但很少。 如果想要接触更好的文章请关注我们公众号,谢谢! 微信公众号:

POJ-3630电话表(考察字典树)

2023每日刷题&#xff08;二十&#xff09; POJ-3630电话表 题目原地址 输入样例&#xff1a; 2 3 911 97625999 91125426 5 113 12340 123440 12345 98346输出结果&#xff1a; NO YES实现代码 #include<iostream> #include<string> #include<cstring>…

AD9371 官方例程 NO-OS 主函数 headless 梳理(一)

AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 &#xff1a; AD9371 官方例程构建及单音信号收发 ad9371_tx_jesd -->util_ad9371_xcvr接口映射&#xff1a; AD9371 官方例程之 tx_jesd 与 xcvr接口映射 AD9371 官方例程 时钟间的关系与生成 &#xff1a; AD9371 官方…