jjzjj

ARMv8-A 地址翻译技术之MMU的前世今生

zevorn 2023-03-28 原文
MMU的重要性不言而喻,支撑操作系统之上的各种复杂应用。但在正式讲MMU之前,我们先说说MMU的发展史,因为ARMv8-A的MMU相当复杂,直接切入正题,会显得比较枯燥。废话不多说,咱们马上开始:

一、前言

关于虚拟内存系统的演变史,MMU在其中扮演了什么样的角色。

早期计算机是没有MMU的概念的,也没有对存储器的抽象,直接将物理内存暴露给程序用。那个时候硬件资源有限,大家都勒紧裤腰带写程序,不敢多浪费一个字节。我曾经规划过一个游戏掌机的开源项目,将早期的街机游戏移植到现代硬件上。

在调研阶段我就发现,这些程序都很小,只有十几KB,但无一例外,都是对内存进行直接操作(有点类似单片机/微控制器编程)。

图 1.1 GAME BOY 掌机

但在那个年代,硬件的迭代速度不如软件快,而彼时的代码业务逻辑已经相当复杂,程序的体积呈指数级增长。

所以早期开发人员,为了使得越来越庞大的程序,能够在资源有限的硬件上运行,发明了ovelay-覆盖块技术,对程序进行分割、分段运行。

但这招治标不治本,并不能保证程序运行的足够顺畅,反而要为程序分段,增加的额外的工作量,这是一件相当痛苦的事情。所以开发人员把目光看向了硬件,决定从软硬两个方向下手。

说到这里,就不得不提一下早期的虚拟化技术。该技术的硬件虚拟化方向,为以后MMU的发展奠定了基础。

“硬件虚拟化”在狭义上是对内存、硬盘等硬件做虚拟化处理(软件为主),配合操作系统以达到分时复用的效果。1964 年,IBM 推出了大名鼎鼎的 System/360。它不仅提供了新型的操作系统,还实现了基于全硬件虚拟化(Full Hardware Virtualization)的虚拟机解决方案。

图 1.2 IBM 员工在调试机器

这其中就包括页式虚拟内存(4k 分页虚拟存储系统)、虚拟磁盘以及 TSS 分时系统。System/360 最多可提供14个虚拟机,每个虚拟机具有 256k 固定虚拟内存。有意思的是,System/360 的开发过程被视为了计算机发展史上最大的一次豪赌,为了研发 System/360,IBM 决定征召六万多名新员工,创建了五座新工厂。即便如此,当时的出货时间仍被不断顺延。

在后续的计算机发展中,内存被操作系统抽象出来,作为地址空间进行统一管理,按需分配给应用程序使用。这样作为内存的硬件细节(容量/类型/厂商/...)被操作系统隐藏了,程序只需要关心地址空间就可以。

同时操作系统引入了虚拟化技术,可以对内存进行"扩容",本质是对内存的分时复用,让每个程序认为自己独占了整个地址空间。但是这样做效率并不高,因为操作系统需要不断地做内存搬运。并且操作系统还要为内存的管理算法,付出许多额外的计算(比如地址翻译),非常浪费性能。

所以我们就需要设计硬件,来代替一些比较繁琐复杂的流程。最好能形成标准流程化操作,这样做成的硬件,可以持续优化(GPU也是这么出现的)。

因此,MMU诞生了,它接替了操作系统内存管理的比较复杂的部分,比如地址翻译;内存访问效率,则交给了 cache(高速缓存)去做,或者提高内存总线的带宽。

在现代操作系统中,衍生了一种更先进的内存管理技术,叫做虚拟内存系统,这是对主存的一种抽象概念。它由硬件异常、物理地址翻译、主存、磁盘文件和内核软件相互配合,共同组成。

虚拟内存系统主要提供了三种能力:

1. 提供主存的高速缓存,加快内存访问速度(高速缓存);

2. 为每个进程提供一致的地址空间,从而简化内存管理;

3. 防止每个进程的地址空间被其他进程所破坏(内存保护)。

图 1.3 虚拟内存系统简易图

MMU的作用,就是将虚拟地址翻译成物理地址。简单来说,CPU会生成一个虚拟地址(Virtual Address)来访问主存(这个地址实际上是操作系统来产生的,最后交给CPU执行)。访问之前,需要先将虚拟地址转换为物理地址,这个过程称作为地址转换(地址映射/地址翻译)。

为进行此操作,需要CPU硬件和操作系统合作,通过内存管理单元(Memory Management Unit)上的硬件翻译地址,来完成虚拟地址到物理地址的转换。MMU利用存储在主存上的查询表(translation table)来翻译虚拟地址,该表的内容由操作系统维护和管理。

图 1.4 MMU地址翻译/转换简化流程

说到这里,你可能对MMU的描述感到云里雾里,但不要紧,接下来我们会对它抽丝剥茧,一点点讲清楚。不过我们还需要对操作系统的虚拟内存系统,做一些更详细的讲解,这样再看MMU,就会非常轻松了。记住,这个先后顺序非常重要。

二、虚拟内存系统的原理

这里我们只探讨虚拟内存系统如何管理虚拟内存的,关于cache部分,我们另说。

一般虚拟内存系统会将虚拟内存,划分为固定大小的块(又叫做最小粒度,一般有4KB、16KB、64KB等大小,其中4KB最流行),这个块我们称作为虚拟页(Virtual Page简称VP),同理将物理内存划分为物理页(Physical Page简称PP),也叫页帧(Page Frame)。

每个虚拟页的首地址,会被维护在一个表内,这个表叫做查询表或页表(Page Table,简称PT),页表内的每一个条目,被称为页表项(Page Table Entry,简称PTE)。

这个页表可能有多级,一般来说,级数越多,能覆盖的虚拟地址范围就越大。在多级页表当中,除最后一级页表之外的所有页表,它的页表项存放的不一定是物理页,也可能是下一级页表的地址。

图 2.1 虚拟内存系统的地址翻译/转换流程

在这个基础上,虚拟系统会产生一个虚拟地址,由虚页号+页偏移组成。虚页号存放的一般是页表项的偏移地址(也可能是多级页表的组合),通过对页表的不断查询,最后找到对应的物理页(的首地址),然后加上虚拟地址的页偏移,就能顺利计算出真实的物理地址。如图2.2所示:

图 2.2 虚拟内存系统的地址翻译/转换详细流程

这个流程,可以用一个很恰当的例子去描述,就是在地图软件上找一个地方儿。

以我在地图上找酒店入住为例,目的地在“四川省-成都市-青羊工业区-成飞路-5号”。于是,我通过手机软件,找到一家到酒店,位置是“四川省-成都市-青羊工业区-成飞路10号”。

哎~,有意思的地方来了, 现在我们以虚拟内存系统的概念,去套这个地址。

首先说虚拟地址(映射为我们生活上划分的位置)。“四川省”是一级页表项的偏移地址,一级页表的范围最大,它有好多个城市(页表项);“成都市”是二级页表项的偏移地址,二级页表的范围次之,它有好多个区(页表项);“青羊工业区”是三级页表项的偏移地址,三级页表的范围已经很小了,但是它也有好多条路(页表项);成飞路就是四级页表项的偏移地址,通过访问成飞路这个页表项,就可以找到它代表的物理页,里面有很多地址(也就是门牌号),目的地在5号,我要住的酒店在10号。

再说对应物理地址。这里从地理角度讲,可以划分为不同的坐标,这里我们就把四川省划分为同等大小的区域,正好被虚拟地址规定的几级页表瓜分。这个区域(路)就是物理页,假设坐标的最小寻址单位,就是通过门牌号寻址。现在,我们再变化一下图2.2,那么你就可以清晰的认识这个过程了。

如图2.3(一定要好好观察,并结合我上面的文字走一遍这个流程,图中的每一个箭头都有意义,应该好好研究):

图 2.3 类比地址转换

同样的道理和方法,就可以找到我酒店的位置,是不是没有想象中那么复杂?而MMU的工作,主要就是做地址的转换、翻译。在这里,虚拟内存系统主要扮演的角色,维护多级页表,控制虚拟地址的映射范围。虚拟系统一般是操作系统的组成部分,这部分工作,也可以说是操作系统帮我们做了。MMU只需要不停地从页表里逐级查找,得到最后的物理页,然后结合虚拟的地址后半部分的页偏移,计算真实的物理地址。

不知道大家有没有注意到,上面我说过,“最后一级页表前的所有页表,它的页表项存放的不一定是物理页,也可能是下一级页表的“页表项的偏移””,反过来讲,每一级页表项,都可以存放物理页和下一级页表的地址,这里我们给存放物理页的页表项叫做块(Block Entry,简称BE);给存放下一级页表地址的页表项叫做TE(Table Entry,简称TE,中文不知道叫啥)。不同的是,每一级页表项存放的块,它的大小是不同的。一般一级页表的块最大,之后逐级递减。

最后,大家可以思考一下,页表级数、块大小的不同,会对地址翻译产生什么样的影响?如果我的CPU只有32位,但是我想实现大于32位地址范围的虚拟地址访问,又该如何操作?

今天先讲到这个,以上全当一道开胃菜儿。关于MMU的故事,我们娓娓道来。关于我上面提出的问题,我们将在下一篇文章揭晓,并为大家介绍ARM的MMU是如何工作的。

有关ARMv8-A 地址翻译技术之MMU的前世今生的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  3. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  4. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  5. ruby-on-rails - 验证电子邮件地址是 Paypal 用户 - 2

    我想验证一个电子邮件地址是否是PayPal用户。是否有API调用来执行此操作?是否有执行此操作的ruby​​库?谢谢 最佳答案 GetVerifiedStatus来自PayPal'sAdaptiveAccounts平台会为您做这件事。PayPal没有任何codesamples或SDKs用于Ruby中的自适应帐户,但我确实找到了编写codeforGetVerifiedStatusinRuby的人.您需要更改该代码以检查他们拥有的帐户类型的唯一更改是更改if@xml['accountStatus']!=nilaccount_status

  6. ruby - Google-api-ruby-client 翻译 API 示例 - 2

    很高兴看到google代码:google-api-ruby-client项目,因为这对我来说意味着Ruby人员可以使用GoogleAPI-s来完善代码。虽然我现在很困惑,因为给出的唯一示例使用Buzz,并且根据我的实验,Google翻译(v2)api的行为必须与google-api-ruby-client中的Buzz完全不同。.我对“Explorer”演示示例很感兴趣——但据我所知,它并不是一个探索器。它所做的只是调用一个Buzz服务,然后浏览它已经知道的关于Buzz服务的事情。对我来说,Explorer应该让您“发现”所公开的服务和方法/功能,而不一定已经知道它们。我很想听听使用这个

  7. ruby-on-rails - 用于门户的 Ruby 技术 - 2

    我刚刚看到whitehouse.gov正在使用drupal作为CMS和门户技术。drupal的优点之一似乎是很容易添加插件,而且编程最少,即重新发明轮子最少。这实际上正是Ruby-on-Rails的DRY理念。所以:drupal的缺点是什么?Rails或其他基于Ruby的技术有哪些不符合whitehouse.org(或其他CMS门户)门户技术的资格? 最佳答案 Whatarethedrawbacksofdrupal?对于Ruby和Rails,这确实是一个相当主观的问题。Drupal是一个可靠的内容管理选项,非常适合面向社区的站点。它

  8. ruby-on-rails - 如果特定语言环境中缺少翻译,如何配置 i18n 以使用 en 语言环境? - 2

    如果特定语言环境中缺少翻译,如何配置i18n以使用en语言环境翻译?当前已插入翻译缺失消息。我正在使用RoR3.1。 最佳答案 找到相似的question这里是答案:#application.rb#railswillfallbacktoconfig.i18n.default_localetranslationconfig.i18n.fallbacks=true#railswillfallbacktoen,nomatterwhatissetasconfig.i18n.default_localeconfig.i18n.fallback

  9. ruby-on-rails - 如何使用 globalize 和 rails 4 以一种形式显示所有翻译字段 - 2

    在使用rails4和https://github.com/globalize/globalize的情况下,我应该如何为我的模型编写表单?用于翻译。我想以一种形式显示所有翻译,如下例所示。我在这里找到了解决方案https://github.com/rilla/batch_translations但我不知道如何实现它。这个“批量翻译”是一个gem还是什么?以及如何安装它。EditingpostEnglish(defaultlocale)SpanishtranslationFrenchtranslation 最佳答案 批处理翻译gem很旧

  10. iNFTnews | 周杰伦18年前未发布的作品Demo,藏在了区块链技术里 - 2

    当音乐碰上区块链技术,会擦出怎样的火花?或许周杰伦已经给了我们答案。8月29日下午,B站独家首发周杰伦限定珍藏Demo独家访谈VCR,周杰伦在VCR里分享了《晴天》《青花瓷》《搁浅》《爱在西元前》四首经典歌曲Demo背后的创作故事,并首次公布18年前未发布的神秘作品《纽约地铁》的Demo。在VCR中,方文山和杰威尔音乐提及到“多亏了区块链技术,现在我们可以将这些Demos,变成独一无二具有收藏价值的艺术品,这些Demos可以在薄盒(国内数藏平台)上听到。”如何将音乐与区块链技术相结合,薄盒方面称:“薄盒作为区块链技术服务方,打破传统对于区块链技术只能作为数字收藏的理解。聚焦于区块链技术赋能,在

随机推荐