首页 > 系统相关 >用户态内存映射

用户态内存映射

时间:2024-09-20 21:21:42浏览次数:3  
标签:里面 struct 映射 用户 页表 虚拟内存 内存

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

用户态内存映射_物理内存

对于堆的申请来讲,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四级页表的概念如下:

用户态内存映射_物理内存_02

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 来创建页表项。

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

用户态内存映射_物理内存_03

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

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

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



标签:里面,struct,映射,用户,页表,虚拟内存,内存
From: https://blog.51cto.com/key3feng/12068632

相关文章

  • 【数据类型】映射map
    小明正在备考英语四级考试,但他的词典太厚了,他记不住哪个单词在哪里。于是他准备开发一个可以直接找某单词在某页的应用。但是,他不会做,整天十分烦恼。好啦,进入正题,大家好,我是@学霸小羊,今天来讲讲map——映射map翻译为映射,是STL中的常用容器。其实,数组就是一种映射,比如:int......
  • 用户体验五要素 - AxureMost
    用户体验五要素-AxureMost用户体验五要素-AxureMost这五个要素自下而上分别是战略层、范围层、结构层、框架层和表现层,它们系统地阐述了如何构建一个成功的用户体验设计过程1.表现层不管是功能型产品还是信息型产品,在表现层都需要为最终产品创建感知体验,其中最主要......
  • 用户验收测试指南5过渡阶段的UAT
    5UAT的位置在本书的这一中心章节中,我们将从准备工作的细节中抽身出来,在沉浸于我们的分步方法的细节之前,先从大局出发。UAT在更大的计划中处于什么位置?它的核心功能和属性是什么?它的总体贡献是什么?本章涉及的主题作为一系列过渡的IS生命周期过渡规划作为过渡阶段的UAT......
  • 从源码看透 Ptmalloc:堆内存分配与释放的背后
    ......
  • 使用swig映射c++function
    swig可以自动生成从c++到其他语言如Java、Python等转换的中间语言,目前swig已经支持很多c++11的特性了,但是这次项目中发现function特性还没有支持,只能自己生成。从网上找了一份Java的java-HowtouseSWIGtowrapstd::functionobjects?-StackOverflow,我需要的c#的,故需要稍......
  • JavaWeb纯小白笔记02:Tomcat的使用:发布项目的三种方式、配置虚拟主机、配置用户名和密
    通过Tomcat进行发布项目的目的是为了提供项目的访问能力:Tomcat作为Web服务器,能够处理HTTP请求和响应,将项目的内容提供给用户进行访问和使用。一.Tomcat发布项目的三种方式:第一种:直接在Tomcat文件夹里的webapps目录创建一个文件夹new放进html文件。f在文件里可以写简单的网......
  • 【操作教程】视频监控系统EasyCVR视频汇聚管理平台如何添加用户和角色?
    视频监控平台/视频监控系统EasyCVR视频汇聚管理平台以其强大的拓展性、灵活的部署方式、高性能的视频能力和智能化的分析能力,为各行各业的视频监控需求提供了优秀的解决方案。通过简单的配置和操作,用户可以轻松地进行远程视频监控、存储和查看,满足各种复杂场景下的监控需求。近......
  • 唤醒沉睡的数据:构建数据飞轮以实现用户挽回
    在当今数据驱动的商业环境中,企业正面临着如何有效利用其庞大数据资产的挑战。特别是在用户流失挽回的场景中,如何通过数据飞轮模型激活沉睡数据,成为企业重要的战略任务。本文将通过探讨全链路营销的数据飞轮构建,展示如何实现数据资产的最大化利用。全链路营销的数据飞轮在全链路营......
  • 华为AC+AP/AP有线口配置有线无线用户统一接入示例
    华为AC+AP/AP有线口配置有线无线用户统一接入示例文章目录华为AC+AP/AP有线口配置有线无线用户统一接入示例前言一、网络拓扑和网段划分二、实验配置1.SW1配置:2.SW2配置:3.AC配置:验证前言在实际的使用场景中,有线网络和无线网络环境通常是共同存在的。例如在办公区......
  • EasyCVR视频汇聚管理平台如何添加用户和角色?
    近期很多用户咨询,在安防监控EasyCVR视频汇聚平台中,如何添加角色或用户。今天我们来介绍一下操作步骤。视频汇聚平台EasyCVR是更偏向于能力层的产品,其核心是视频的汇聚管理与流媒体分发,因此,目前能分配给用户的是【视频调阅】和【录像回放】权限,其他功能资源的分配还在产品开发计划中......