『内存中的操作系统』如何高效, 灵活的虚拟化内存(1)

往期精选

『内存中的操作系统』虚拟化是什么

『内存中的操作系统』内存虚拟化又是什么

思维模型
  1. 如何实现从虚拟地址到物理地址

1. 如何实现从虚拟地址到物理地址

在上文中, 我们讲解了如何虚拟化内存的大致思路, 并讲解了在设计之前的目标和准则. 那么接下来我们就要尝试进行详细设计我们的虚拟化内存方式.

我们最容易想到的就是基于硬件来直接做转换, 也就是硬件对每次内存访问进行处理(即指令获取、数据读取或写入),将指令中的虚拟(virtual)地址转换为数据实际存储的物理(physical)地址. 硬件对每次内存访问进行处理(即指令获取、数据读取或写入),将指令中的虚拟(virtual)地址转换为数据实际存储的物理(physical)地址.

这样的话, 我们同时还需要操作系统来设置好硬件, 以完成正确的地址转换, 同时需要管理内存, 记录已经使用和空闲的内存位置, 防止进程对内存的不合理使用.

1.1 地址转换

这个就是在20世纪50年代后期出现的虚拟内存的设计思路, 为了实现上面的目标, CPU增加了两个硬件寄存器:基址(base)寄存器和界限(bound)寄存器,有时称为限制(limit)寄存器。这组基址和界限寄存器,让我们能够将地址空间放在物理内存的任何位置,同时又能确保进程只能访问自己的地址空间。即:

实际物理地址 = 虚拟地址 + 基址(base)

进程中使用的内存引用都是虚拟地址(virtual address),硬件接下来将虚拟地址加上基址寄存器中的内容,得到物理地址(physical address),再发给内存系统。

而界限寄存器则可以保证超过界限的内存访问都会被阻止, 系统会报错, 设置会终止进程, 从而可以有效的防止对内存的不合理使用.

这种基址寄存器配合界限寄存器的硬件结构是芯片中的(每个CPU一对)。有时我们将CPU的这个负责地址转换的部分统称为内存管理单元(MemoryManagement Unit,MMU)。这个在我们现在的硬件中都是有的, 不过它拥有的比我们这里说的更复杂的内容.

1.2 分段

那么上面的设计有没有什么问题呢? 答案其实很清晰, 那就是逻辑过于简单了, 虽然很多时候设计越简单越好, 但是前提是要满足复杂的现实场景. 根据上面的设计, 我们可以很容易画出我们目前的内存结构:

这里你可能已经看到问题在哪了, 那就是栈和堆之间,有一大块“空闲”空间。如果我们将整个地址空间放入物理内存,那么栈和堆之间的空间并没有被进程使用,却依然占用了实际的物理内存。因此,简单的通过基址寄存器和界限寄存器实现的虚拟内存很浪费。

另外,如果剩余物理内存无法提供连续区域来放置完整的地址空间,进程便无法运行。这种基址加界限的方式看来并不像我们期望的那样灵活。

所以只有基址寄存器和界限寄存器并不能满足实际的内存使用需求. 我们还需要更为复杂的设计, 也就是分段(segmentation). 分段并不是一个新概念,它甚至可以追溯到20世纪60年代初期。这个想法很简单,在MMU中引入不止一个基址和界限寄存器对,而是给地址空间内的每个逻辑段(segment)一对。

一个段只是地址空间里的一个连续定长的区域,在典型的地址空间里有 3 个逻辑不同的段:代码、栈和堆。分段的机制使得操作系统能够将不同的段放到不同的物理内存区域,从而避免了虚拟地址空间中的未使用部分占用物理内存。

那么根据我们的设计, 内存结构可能就是如下的样子:

从图中可以看到,只有已用的内存才在物理内存中分配空间,因此可以容纳巨大的地址空间,其中包含大量未使用的地址空间(有时又称为稀疏地址空间,sparseaddress spaces)。你会想到,需要MMU中的硬件结构来支持分段:在这种情况下,需要一组3对基址和界限寄存器。下面是一组示例:

根据我们的示例, 我们来看一个例子:

假设现在要引用虚拟地址100(在代码段中),MMU将基址值加上偏移量(100)得到实际的物理地址:100 + 32KB = 32868。然后它会检查该地址是否在界限内(100小于2KB),发现是的,于是发起对物理地址32868的引用。

如果我们有学过Java虚拟机JVM的内存结构, 就会发现其中的: 堆内存, 方法区和栈的设计思路就是我们这里的设计思路.

有趣的知识: segmentation fault

如果我们试图访问非法的地址,例如7KB,它超出了堆的边界呢?你可以想象发生的情况:硬件会发现该地址越界,因此陷入操作系统,很可能导致终止出错进程。这就是每个C程序员都感到恐慌的术语的来源:段异常(segmentationviolation)或段错误(segmentation fault)。

来看一个堆中的地址,虚拟地址4200(同样参考图16.1)。如果用虚拟地址4200加上堆的基址(34KB),得到物理地址39016,这不是正确的地址。我们首先应该先减去堆的偏移量,即该地址指的是这个段中的哪个字节。因为堆从虚拟地址4K(4096)开始,4200的偏移量实际上是4200减去4096,即104,然后用这个偏移量(104)加上基址寄存器中的物理地址(34KB),得到真正的物理地址34920。

总结

到这里, 我们已经有了虚拟化内存的基本思路, 沿着这条思路, 让我们在接下来的文章继续细化我们的设计. 来达到高效,灵活的效果.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容