ARM(5)内存管理单元MMU

一、虚拟地址和物理地址

    首先,计算机系统的内存被组成一个由M个连续的字节大小组成的数组。每字节都会有一个唯一的物理地址。CPU访问内存最简单的方式就是使用物理地址。如下图:

图 1 物理地址,物理寻址

    而现在都是采用的都是虚拟寻址的方法。CPU生成一个虚拟地址(VA),然后MMU(Memory Management Unit 内存管理单元) 将虚拟地址翻译成实际的物理地址,然后再进行物理寻址。

图2虚拟寻址

设想以下问题

1. 假如内存不足会怎么样?(对于一台32位系统来说,可以使用的内存有:2^32 bytes = 4GB);内存不足,超出内存空间会导致崩溃(crash)(例如32位系统,只有1GB RAM)

2. 内存碎片化:如果连续分配内存,程序可能找不到合适的空间(run out of space),即使有空间,但是不连续。

3. 多个程序指向相同的地址:不同程序间读写相同的内容,导致数据污染或崩溃

    怎么解决?让每一个程序拥有自己的虚拟内存空间。把程序的内存空间映射到物理内存(物理内存不足时把暂时不用的替换到硬盘上)。

  • 虚拟内存

虚拟内存是一种计算机系统的内存管理技术,它允许程序使用比实际物理内存更大的内存空间。

    在虚拟内存系统中,每个进程被分配了一个连续的虚拟地址空间,它通常比实际的物理内存大小要大得多。虚拟地址空间被划分为多个固定大小的单元,称为页面(pages)或虚拟页(virtual pages)。相应地,物理内存也被划分为与虚拟页大小相匹配的页面帧(page frames)。

    当程序访问虚拟内存中的某个地址时,操作系统通过地址映射机制将虚拟地址转换为物理地址。这个映射过程涉及将虚拟页从磁盘上的页面文件(page file)中加载到物理内存中的一个页面帧中。这样,虚拟内存可以提供比实际物理内存更大的可用内存空间。

    虚拟内存的主要优势是它允许在内存不足的情况下运行更大的程序或处理更大的数据集。它还提供了更好的内存管理保护机制,使不同的进程能够相互隔离和保护彼此的内存空间。

    虚拟内存本身不直接占用物理空间。虚拟内存是一种内存管理技术,它通过将部分数据存储在磁盘上的页面文件中,以释放物理内存并提供更大的可用内存空间。因此,虚拟内存的数据被分为两部分:存储在物理内存中的活动数据和存储在磁盘中的交换数据。

总而言之,虚拟内存是一种将物理内存和磁盘空间结合使用的内存管理技术,它提供了比实际物理内存更大的内存空间,并通过页面映射机制实现虚拟地址到物理地址的转换。它是现代操作系统中的重要组成部分,为程序提供了更大的内存空间和更好的内存管理功能。

虚拟页可以分为三种状态:

  1. 未分配的:未分配的页没有任何数据。
  2. 缓存的:当前已在物理内存中的已分配页。
  3. 未缓存的:未缓存在物理内存的已分配页。

虚拟内存是怎么解决3个问题:

1.内存不足时:当向系统申请内存但内存不足时,系统会把根据置换算法把暂进不用的内存置换到硬盘里,更新映射关系到硬盘上,再更新新申请的内存映射关系,让我们产生无限内存的错觉。(交换到硬盘后会导致性能下降,硬盘读取速度比内存慢太多了)。例如下面这个例子,程序0,1,2分别加载了物理地址的0,1,2。此时程序3进来,也需要申请内存。然后就根据算法先把内存腾出来,腾出来的放到磁盘上,再把腾出来的空间给程序3。这样就可以解决内存不足的问题而不会导致崩溃。

2.内存碎片:程序通过自身的映射表可以随意找到合适的物理内存,而不一定需要连续分配。

3.程序间相同的地址:

即使程序的地址相同,但是每个程序通过自己的映射表映射到不同的物理内存而不会互相产生干扰。但是程序间相互独立一定是好的吗?并不是,因为有些内存是需要共享的。例如不同的程序会共享系统文件,系统选择框等。让程序间实现共享内存的方法是把地址指向相同的物理内存。

内存映射主要由操作系统的内存管理单元(Memory Management Unit, MMU)管理操作的,一切都是同它来掌控。

程序访问内存的步骤:地址翻译      

1. 程序指定加载一个逻辑地址

2. 计算机通过映射把逻辑地址转换成物理地址

3. 如果物理地址不在内存中,操作系统会把它从硬盘中加载到内存里,更新映射关系(原来是指向disk的,现在指向内存)

4. 计算机通过物理地址把内存内容读取出来并且返回给程序

2.1 为什么需要虚拟地址

虚拟地址的引入主要是为了满足以下几个需求和提供相应的优势:

    1. 内存隔离:每个进程都拥有自己独立的虚拟地址空间,使得进程之间的内存彼此隔离。这样,一个进程无法直接访问另一个进程的内存,提高了系统的安全性和稳定性。

    2. 大内存支持:虚拟地址空间可以比实际的物理内存空间大得多。这使得操作系统能够支持大容量的内存需求,可以运行更大的应用程序和处理更多的数据。

    3. 内存管理灵活性:虚拟地址空间的使用可以动态地进行管理。操作系统可以根据需要将虚拟地址映射到物理内存或其他存储设备上,实现内存的灵活分配和回收,包括页面置换、页面回写和内存映射文件等技术。

    4. 虚拟内存映射:虚拟地址与物理地址之间的映射关系可以通过页表等数据结构来实现。这使得操作系统能够将虚拟地址转换为物理地址,从而实现对内存的透明访问。

    5. 内存保护:虚拟地址空间允许操作系统对内存区域进行权限控制和访问限制。通过设置页面级别的访问权限和保护位,操作系统可以防止非法访问和保护系统关键数据和代码。

     总之,虚拟地址的引入使得操作系统能够提供更大的地址空间、更好的内存隔离、灵活的内存管理和保护机制。它为多进程环境下的程序提供了一种抽象层,使得程序可以使用独立且安全的地址空间,同时有效利用系统的资源。

  1. 物理地址PA:物理地址是计算机内存中实际的硬件地址。它是由计算机系统中的内存管理单元(MMU)转换而来,用于直接访问主存储器中的数据。物理地址是一个唯一的标识符,用于定位内存中的特定字节或字。
  2. 虚拟地址VA:虚拟地址是一种抽象的地址,由进程或程序使用。它是在虚拟内存系统中使用的地址,与物理地址相对应。虚拟地址空间被划分为不同的页(或页框),并通过地址转换机制映射到物理内存中的相应页框。虚拟地址提供了一种独立于实际物理内存布局的方式来访问内存,使得每个进程都有自己独立的地址空间。

     那么虚拟地址是怎么转化成物理地址的呢?这就涉及到虚拟内存,页表等等新东西,接下来看。

三、页Page/页表/页表项(PTE)

MMU是负责把虚拟地址映射为物理地址,但凡"映射"都要解决两个问题:映射的最小单位(粒度)和映射的规则。

     页(Page):MMU中VA到PA映射的最小单位称为页(Page),映射的最低粒度是单个虚拟页到物理页,页大小通常是4K,即一次最少要把4K大小的VA页块整体映射到4K的PA页块(从0开始4K对齐划分页块),页内偏移不变(低12bit),用于索引4K空间的页。

      页表(Page Table),就是一个个页表条目PTE(Page Table Entry)组成的数组,每一条称为一个页表条目(Page Table Entry,即PTE)。

  MMU软件配置的核心是页表(Page Table),它描述MMU的映射规则,即虚拟内存哪(几)个页映射到物理内存哪(几)个页帧。整个页表保存在片外内存,MMU通过查找页表确定一个VA应该映射到什么PA,以及是否有权限映射。

    映射规则如下图:

    例:如VA的一页0x30004000~0x30004fff被映射到PA的一页 0x00008000~0x00008fff,当CPU执行单元访问虚拟地址0x30004008,实际访问的物理地址是0x00008008(0x30004008和0x00008008分别位于虚实两套地址空间,互不相干,不存在重叠和冲突)。以页为最小单位,就是不能把VA中某一页划分成几小块分别映射到不同PA,也不能把VA中属于不同页的碎块映射到PA某一页的不同部分,必须页对页(4K大小)整体映射。

----------------------------

Q:页表为什么保存在主存中?

A:页表保存在片外内存的主要原因是空间的限制和灵活性的需求。

1. 空间限制:页表可能非常庞大(32bit:1 billion PTE!),特别是在具有大型虚拟地址空间的系统中。将整个页表保存在处理器的寄存器或缓存中是不切实际的,因为这些存储器有限的容量无法容纳如此大的页表。片外内存(主存)提供了更大的存储容量,可以容纳大型的页表结构。

2. 灵活性:页表的大小和结构可能随着进程的需要而变化。将页表保存在片外内存中可以更容易地进行动态调整和管理。当页表需要扩展或收缩时,可以通过修改指向页表的指针或重新分配内存来实现,而不需要对处理器的硬件结构进行改动。

3. 虚拟化支持:在虚拟化环境中,多个虚拟机可能同时运行在同一台物理机上。每个虚拟机都有自己的独立虚拟地址空间和页表。通过将页表保存在片外内存中,不同的虚拟机可以独立管理和访问自己的页表,增加了虚拟化的灵活性和隔离性。

    虽然将页表保存在片外内存中增加了访问开销(因为需要额外的内存访问),但这种折衷是为了满足大型地址空间和动态的内存管理需求。同时,使用高速缓存(如TLB)来缓存最近使用的页表项可以在一定程度上减少访问延迟。

----------------------------------

四、虚拟地址和页表条目的关系

    在第3节中描述了通过页表条目找到物理内存中的页。那么接下来再来看看给定一个虚拟地址,怎么找到它对应的页表条目PTE。

    一个n位的虚拟地址包含两部分:一个p位的虚拟页面偏移(VPO)和一个(n-p)位的虚拟页号(VPN)。MMU正是利用了VPN来选择合适的PTE。然后将PTE中PPN和VPO串联起来,就得到了实际的物理地址。

图4-1 虚拟地址和PTE和物理地址

    至此,来简要理一下简要流程。

1.CPU生成一个虚拟地址,并把它传给MMU。

2.MMU生成PTE地址,请求高速内存/内存返回实际数据。

3.内存向MMU返回PTE。

4.MMU按照图4-1逻辑,构建物理地址PA,并请求内存

5.主存返回物理地址存储的数据


五、TLB (Translation Lookaside Buffers)

 但如果MMU每次地址转换都到位于外部内存的页表上查找PTE,转换速度就会大大降低,内存的速度需要几百个CPU周期。为了减少这个开销,于是出现了TLB (Translation Lookaside Buffers)即转换快表,又简称快表,可以理解为MMU内部专用的存放页表的cache,保存着最近使用的PTE乃至全部页表。

    MMU接收到虚拟地址后,首先在TLB中查找,如果找到该VA对应的PTE就直接转换,找不到再去外存页表查找,并置换进TLB。TLB属于片上SRAM,访问速度快,通过TLB缓存PTE可以节省MMU访问外存页表的时间,从而加速虚实地址转换。TLB和CPU cache的工作原理一样,只是TLB专用于为MMU缓存页表。

    带有TLB的虚拟地址转化过程如图5-1所示。在TLB不命中的时候,从内存中返回的PTE会被缓存在TLB中,可能会覆盖一个已存在的条目。

六、多级页表

    

    Q:为什么要采取这种多级页表的形式?

    A:省内存空间。

    多级页表相较于单级页表可以节省空间的主要原因是多级页表采用了分层的结构,使得整个页表不需要一次性加载到内存中(如上图中的2^36个PTE)。这样,在实际使用中,只需要加载当前进程所使用的部分页表(4*2^9个PTE)从而减少了内存的占用。

    采用多级页表的主要原因有以下几点:

    1. 空间效率:多级页表可以根据需要动态分配和释放内存空间。相比于单级页表,多级页表可以节省大量的内存空间。在单级页表中,每个虚拟页都需要一个对应的页表项,而多级页表可以根据需要只分配实际使用的页表项,减少了内存开销。

    2. 快速访问:多级页表可以提高地址转换的速度。在大型内存空间中,使用单级页表需要遍历整个页表来进行地址映射,这会导致访问速度变慢。而多级页表通过分层的结构,可以将大型页表划分为多个小的页表,每次只需要查找相应的页表,从而加快了地址转换的速度。

    3. 灵活性:多级页表提供了更大的灵活性和可扩展性。通过增加额外的级别,可以处理更大的内存空间。同时,多级页表可以根据实际需求进行调整和优化,以适应不同的应用程序和系统环境。

    总的来说,采用多级页表可以提高内存管理的效率和灵活性,减少内存开销,并提高地址转换的速度。这使得操作系统能够更好地管理大型内存空间和处理复杂的内存访问需求。

七、MMU映射失败的几种情况

    1.访问了受内核保护的页面,或者访问了只读的页面,此时内核会抛出段错误。

    2.VP和PP没有产生映射关系,但是数据页已经被其他进程加载到内存中了,此时只需要建立VP和PP的映射关系,称为次级缺页中断。

    3.VP和PP没有产生映射关系,数据页也没有被加载到内存中(在磁盘上),此时需要发生磁盘io从磁盘中加载页到内存中,还需要建立VP和PP的映射关系,称为严重缺页中断。

    除了第一点,第二第三都会以内核降低自身运行速度来修复,也就是通过中断形成页表映射,然后再重新执行引起中断的命令(此时已经更新了物理内存和PTE,数据页已经在内存中并且建立映射关系了)。

如果物理页不在内存中,CPU生成一个缺页异常(page fault exception):

     1. CPU跳转到系统缺页处做清除置换

     2. 系统选择某一页从内存中移除并写入硬盘中(这里涉及页面转换算法,如最优算法、先进先出算法、最近最久未使用算法、时钟算法、最不常用算法)

     3. 如果被选中从内存中移除的页面是脏数据,必须把它先写到硬盘上

     4. 从硬盘中读取缺页异常的页面并写到内存中

     5. 更新页表的映射关系

     6. 系统跳转回到引起缺页异常的指令处

参考链接:

Virtual Memory: 14 Summary (youtube.com) (合集1-14)

【MMU篇】一文总结ARMv8中的MMU架构_armv8 mmu-CSDN博客

https://zhuanlan.zhihu.com/p/484183354

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

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

相关文章

gitlab保护分支设置

版本:gitlab10.2.2 一旦设置master分支被保护,除了管理员之外的任何用户都无法直接向master提交代码,只要提交代码就会报错 # git push -u origin master Total 0 (delta 0), reused 0 (delta 0) remote: GitLab: You are not allowed to pu…

在CentOS系统下实现准实时SFTP上传指定目录下前2分钟的文件

在CentOS系统下实现准实时SFTP上传指定目录下前2分钟的文件 引言准备工作编写Shell脚本执行脚本定时执行脚本注意事项结论引言 在企业级的文件同步和备份场景中,经常需要将本地目录中最新生成的文件(如前2分钟内生成的文件)快速上传到远程服务器的指定目录。为了实现这一目…

unity 屏幕波动反馈打击效果(附资源下载)

unity 屏幕波动反馈打击效果 一枪打出去整个屏幕都回波动的效果反馈。 知识点: 1、动画事件 2、屏幕后处理 效果如图:(波动速度浮动都可调整) 附件下载

【互联网业务风控】

1. 不同场景下的业务风控 1.1 账户业务风控 1.1.1账户安全 • 账号安全是所有强账号体系应用的基础, 强账号体系,如电商、网游、第三方支付、社交网络、即时通讯等;是需要登录后产生数据和交互的应用, 弱账号体, 如搜索、导航、…

关键词提取技术:TF-IDF 和 TextRank 简介

关键词提取是自然语言处理中的重要任务之一,用于自动提取文档中最能代表其内容的词汇。两种常用的关键词提取技术是 TF-IDF 和 TextRank。它们的工作机制和应用场景有所不同,下面将详细解释这两种技术。 1. TF-IDF(Term Frequency - Inverse…

Python | Leetcode Python题解之第485题最大连续1的个数

题目: 题解: class Solution:def findMaxConsecutiveOnes(self, nums: List[int]) -> int:maxCount count 0for i, num in enumerate(nums):if num 1:count 1else:maxCount max(maxCount, count)count 0maxCount max(maxCount, count)return …

未来智慧建筑:人工智能技术的无限可能

随着科技的不断发展,人工智能技术正逐渐渗透到各行各业,其中,在智能建筑领域的应用备受瞩目。智能建筑结合了传统建筑与先进科技的完美融合,在提高建筑效率、节能环保、增强安全性等方面发挥着重要作用。本文将探讨人工智能技术在…

MyBatis的占位符(day36)

1 学习目标 重点掌握#{}占位符的使用 2 MyBatis的占位符介绍 #{}占位符: 相当于JDBC中的问号(?)占位符&#xff0c;是为SQL语句中的值进行占位&#xff0c;如果参数值是字符串或者日期类型&#xff0c;会进行转义处理 我们使用#{}写的SQL语句: <update id"delete…

蓝牙资讯|苹果AirPods Pro 2耳机推送开发者Beta固件

科技媒体 MacRumors 报道&#xff0c;苹果公司邀请开发者&#xff0c;针对 Lightning 和 USB-C 接口的 AirPods Pro 2 耳机&#xff0c;推送了新的 7B5013d 固件版本&#xff0c;较之前的 7B5013c 有所提升。 苹果未来会向所有 AirPods Pro 2 用户推送本次固件更新&#xff0…

react18中实现简易增删改查useReducer搭配useContext的高级用法

useReducer和useContext前面有单独介绍过&#xff0c;上手不难&#xff0c;现在我们把这两个api结合起来使用&#xff0c;该怎么用&#xff1f;还是结合之前的简易增删改查的demo&#xff0c;熟悉vue的应该可以看出&#xff0c;useReducer类似于vuex&#xff0c;useContext类似…

springboot项目通过maven的profile功能实现通过不同文件夹的方式来组织不同环境配置文件

写在前面 本文看下springboot项目如何通过文件夹的方式来组织不同环境配置文件。 1&#xff1a;正文 一般的我们写springboot项目时配置文件是这个样子的&#xff1a; appliction.yaml --> 通过spring.profiles.activexxx来激活某个指定后缀的配置文件 application-evn1…

小程序项目实践(一)--项目的初始化以及前期的准备工作

目录 1.起步 1.1 uni-app 简介 1.2 开发工具 1.2.1 下载 HBuilderX 1.2.2 安装 HBuilderX 1.2.3 安装 scss/sass 编译 1.2.4 快捷键方案切换 1.2.5 修改编辑器的基本设置 1.3 新建 uni-app 项目 1.4 目录结构 1.5 把项目运行到微信开发者工具 1.6 使用 Git 管理项目 …

SpringBoot3响应式编程全套-R2DBC

目录 传送门前言一、R2DBC概念二、Spring Data R2DBC1、整合1.1、导入依赖1.2、编写配置 2、声明式接口&#xff1a;R2dbcRepository2.1、Repository接口2.2、自定义Converter2.3、配置生效 3、编程式组件 三、RBAC-SQL练习1、1-12、1-N 四、最佳实践五、附录 传送门 SpringMV…

python配合yolov11开发分类训练软件

上一篇文件写了用yolo分类模型开发分类软件&#xff0c;这边文章在上个分类软件的基础上加入训练功能环境配置:pycharm&#xff0c;PySide6 6.6.1 &#xff0c;PySide6-Addons 6.6.1&#xff0c;PySide6-Essentials 6.6.1&#xff0c;torch 2.3.1cu121&#xff0c;torchaudio 2…

Spring AI Java程序员的AI之Spring AI(三)RAG实战

Spring AI之RAG实战与原理分析 前言RAGDocumentDocumentReaderDocumentTransformerDocumentWriter VectorStoreSimpleVectorStoreRedisVectorStore元数据搜索组装提示词 前言 检索增强生成&#xff08;RAG&#xff09;是一种结合信息检索和生成模型的技术&#xff0c;用于将相…

C语言——数组

1.数组的概念 数组是一组相同类型元素的集合&#xff1b; 数组中可以存放1个或多个元素&#xff0c;但数组元素个数不能为0。 同时数组可以分为一维数组和多维数组&#xff0c;多维数组一般常见 是二维数组。 2.一维数组的创建和初始化 一维数组的创建的基本语法&#xff1a; …

大数据-168 Elasticsearch 单机云服务器部署运行 详细流程

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

【C++】类和对象(类的默认成员函数)

目录 一.构造函数 二.析构函数 三.拷贝构造函数 四.赋值运算符重载 五.取地址运算符重载 默认成员函数就是用户没有显式实现&#xff0c;编译器会自动生成的成员函数称为默认成员函数。一个类&#xff0c;我们不写的情况下编译器会默认生成以下6个默认成员函数。 一.构造…

目标检测中的损失函数

损失函数是用来衡量模型与数据的匹配程度的&#xff0c;也是模型权重更新的基础。计算损失产生模型权重的梯度&#xff0c;随后通过反向传播算法&#xff0c;模型权重得以更新进而更好地适应数据。一般情况下&#xff0c;目标损失函数包含两部分损失&#xff0c;一个是目标框分…

Vue3万能初始化

项目创建后第一步 项目创建&#xff1a;Vue3创建-CSDN博客 创建后执行下面 删除默认提供的HelloWorld.vue组件和src/APP.vue中的默认样式和内容。 App.vue&#xff0c;代码&#xff1a; <template></template><script setup></script><style&g…