【操作系统】虚拟内存(一)

一个系统中的进程是与其他进程共享CPU和主存资源的(win系统就是内存条内存),然而主存资源是有限的,如果进程太多,那内存资源根本就满足不了。为了更加有效的管理内存并且减少出错,现代操作系统提供了一种对主存的抽象概念,叫虚拟内存
虚拟内存是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的完美交互,它为每个进程提供了一个大的、一致的和私有的地址空间

一、寻址

1.物理寻址

早期的PC的CPU访问内存方式是使用物理地址,称之为物理寻址。如图1
在这里插入图片描述

图1

图1展示的是一条加载指令,它读取从物理地址4处开始的4字节字,当CPU执行这条加载指令时,会生存一个有效的物理地址,通过内存总线,把它传递给主存。主存取出从物理地址4处开始的4字节字,并将它返回给CPU,CPU会将它存放在一个寄存器里。

2.虚拟寻址

现代处理器使用的是虚拟寻址的寻址方式,如图2:
在这里插入图片描述

图2

CPU通过生存一个虚拟地址来访问主存,这个虚拟地址在被送到内存之前先转换为适当的物理地址。将一个虚拟地址转换为物理地址的任务叫做地址翻译。CPU芯片上有个内存管理单元(MMU)的专用硬件,利用存放在主存中的查询表来动态的翻译虚拟地址,该表由操作系统管理。

二、地址空间

虚拟地址空间是一个非负整数地址的有序集合:

{0, 1,2,…}

如果地址空间中的整数是连续的,那么我们说它是一个线性地址空间。
一个地址空间的大小由表示最大地址所需要的位数来描述的。
例如,一个包含N=2^n个地址的虚拟地址空间就叫做一个n为地址空间。win系统的x86架构是32位地址系统,x64是64位地址系统。
主存中的每字节都有一个选自虚拟地址空间的虚拟地址和一个选自物理地址空间的物理地址。

三、虚拟内存作为缓冲工具

虚拟内存被组织为一个由存放在磁盘上的N个连续的字节大小的单元组成的数组。每字节都有一个唯一的虚拟地址,作为到数组的索引。磁盘上数组的内容被缓存在主存中。
磁盘上的数据块被分割成块,这些块作为磁盘和主存之间的传输单元。VM系统通过将虚拟内存分割为称为虚拟页的大小固定的块来处理这个问题。每个虚拟页的大小为P=2^p字节。物理内存被分割为物理页,大小也为P字节(物理页被称为页帧)。
虚拟页面的集合分为三个不相交的子集:

  • 未分配的:VM系统还未分配(或者创建)的页。未分配的块没有任何数据和它们相关联,因此也就不占用任何磁盘空间。
  • 缓存的:当前已缓存在物理内存中的已分配页。
  • 未缓存的:未缓存在物理内存中已分配页。

VM系统使用主存作为缓存示例:
在这里插入图片描述

图3

一共有8个虚拟页的小虚拟内存,虚拟页0和3还未被分配,因此在磁盘上还不存在。虚拟页1、4、6被缓存在物理内存中。页2、5和7已经被分配了,但是还并未被缓存在主存中。

1.DRAM缓存的组织结构

为清晰理解存储层次结构中不同的缓存概念,使用术语SRAM缓存来表示位于CPU和主存之间的L1、L2、L3高速缓存,用术语DRAM缓存来表示虚拟内存系统的缓存,它在主存中缓存虚拟页。

2.页表

同任何缓存一样,虚拟内存系统中必须有某种方法来判定一个虚拟页是否缓存在DRAM中的某个地方。如果是,系统还必须确定这个虚拟页存放在哪个物理页中,如果不命中,系统必须判定这个虚拟页存放在磁盘的哪个位置,在物理内存中选择一个牺牲页,并将虚拟页从磁盘复制到DRAM中,替换这个牺牲页。
上述这些功能是由操作系统软件、MMU中的地址翻译硬件和一个存放在物理内存中叫做页表(page table)的数据结构,页表将虚拟页映射到物理页。每次地址翻译硬件将一个虚拟地址转换为物理地址时,都会读取页表。操作系统维护页表的内容,以及在磁盘与DRAM之间来回传送页表。
页表的基本组织结构如下图:
在这里插入图片描述

图4

页表就是一个页表条目的数组。虚拟地址空间中的每个页在页表中一个固定偏移量处都有一个PTE。上图中假设每个PTE由一个有效位和一个n位地址字段组成。有效位表明了该虚拟页当前是否被缓存在DRAM中,如果设置有效位,那么地址字段就表示DRAM中相应的物理页的起始位置,这个物理页中缓存了该虚拟页。若未设置有效位,那么一个空地址表示这个虚拟页还未被分配。
上图4中展示了一个有8个虚拟页和4个物理页的系统页表。

  • 四个虚拟页(VP1、VP2、VP4、VP7)当前被缓存在DRAM中。
  • 两个页(VP0、VP5)还未被分配。
  • VP3、VP6已经被分配,但是还未被缓存。
3.缺页

在虚拟内存的习惯说法中,DRAM缓存不命中称为缺页。举例说明:
缺页之前
在这里插入图片描述

图5

CPU引用了VP3中的一个字,VP3并未缓存在DRAM中。地址翻译硬件从内存中读取PTE3,从有效位推断出VP3未被缓存,并且触发一个缺页异常。之后按如下流程处理:

  1. 缺页异常调用内核中的缺页异常处理程序,该程序会选择牺牲一个牺牲页,此例中是存放在PP3的VP4。
  2. 如果VP4已经被修改了,那么内核就会将它复制会磁盘。无论哪种情况,内核都会修改VP4的页表条目,反映出VP4不再缓存在主存中。
  3. 内核从磁盘复制VP3到内存中的PP3,更新PTE3,返回返回。
  4. 当异常处理程序返回时,它会重新启动导致缺页的指令,该指令会把导致缺页的虚拟地址重发送到地址翻译硬件。
  5. 此时VP3已经缓存在主存中,那么页也能正常命中了。

缺页之后
缺页之后的处理如图6
在这里插入图片描述

图6

四、虚拟内存作为内存管理工具

操作系统为每个进程提供了一个独立的页表,也就是一个独立的虚拟地址空间,如图7
在这里插入图片描述

图7

注意:多个虚拟页面可以映射到同一个共享物理页面上。

VM简化了链接和加载、代码和数据共享,以及应用程序的内存分配。

  • 简化链接。独立的地址空间运行每个进程的内存映像使用相同的基本格式,而不管代码和数据实际存放在物理内存的何处。
  • 简化加载。 虚拟内存还使得容易向内存中加载可执行文件和共享对象文件。加载器从不从磁盘到内存实际复制任何数据。在每个页初次被引用时,要么是CPU取指令时引用的,要么是一条正在执行的指令引用一个内存位置时引用的,虚拟内存系统会按照需要自动地调入数据页。
  • 简化共享。 独立地址空间为操作系统提供了一个管理用户进程和操作系统自身之间共享的一致机制。相同的操作系统内核代码,每个进程之间都是共享的。
  • 简化内存分配。 当操作系统给进程分配K个连续的虚拟页面,这连续的虚拟页面可以映射到K个人也的物理页面。

五、虚拟内存作为内存保护工具

现代计算机系统必须为操作系统提供手段来控制对内存系统的访问。不应该发生以下事情:

  1. 不应该允许用户进程修改它的只读代码段;
  2. 不应该允许用户进程读或修改任何内核中的代码和数据结构;
  3. 不应该允许用户进程读或者写其它进程的私有内存;
  4. 不应用允许用户进程修改任何与其他进程共享的虚拟页面,除非所有的共享者都显示的允许它这么做。

通过在PTE上添加一些二外的许可位来控制对一个虚拟页面内容的访问则十分简单了,大致思想如图8
在这里插入图片描述

图8

每个PTE中添加三个许可位。

  • SUP位表示进程是否必须运行在内核(超级用户)模式下才能访问该页。运行在内核模式中的进程可以范围任何页面,但是运行中用户模式下的进程只允许访问那些SUP为0的页面。
  • READ位和WRITE位控制对页面的读和写权限。

如果一条指令违反了这些许可条件,那么CPU就触发一个一般保护故障,将控制传递给一个内核中的异常处理程序。产生一个“段错误”。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章