《操作系统导论》第二部分 内存虚拟化 P2 地址转换机制

C3 机制:地址转换

3.1 地址转换机制概述

(1) 内存虚拟化的高效,控制和灵活性

在CPU虚拟化时,使用了受限直接访问 LDE,LDE背后的想法很简单:让程序运行的大部分指令直接访问硬件,在一些关键点(进程发生系统调用和发生时钟中断)由操作系统介入来确保高效和控制

对内存虚拟化时,同样追求高效和控制,高效决定我们要利用硬件的支持控制意味着操作系统确保每个应用只能访问自己的内存空间,要保护应用程序不会互相影响,更不会影响操作系统,灵活性即希望程序能以任何方式访问它们自己的内存空间,从而让系统更容易编程

(2) 地址转换

为了完成这些,采用了称为基于硬件的地址转换,即地址转换,利用地址转换,硬件对每次内存访问进行处理,将指令中的虚拟地址转换为数据实际存储的物理地址,因此在每次内存引用时,硬件都会进行地址转换,将应用程序的内存引用重定位到内存中实际所在的位置

仅仅依靠硬件不足以实现虚拟内存,操作系统必须在关键的位置介入,设置好硬件,以便完成正确的地址转换,操作系统必须管理内存,记录被占用和空闲的内存位置,保存对内存使用的控制

3.2 假设

为了更好理解内存的虚拟化和地址转换机制,先做几个假设:
假设1,假设用户的地址空间必须连续地存放在物理内存中
架设2,假设地址空间不是很大,小于物理内存的大小
假设3,假设每个地址空间大小相等

3.3 重定位的一个例子

先看一个简单的例子,一个进程中执行一段指令,它从内存中加载一个值x,并对它加3,再将它存回内存,其功能为3条指令大致如下:

movl 0x0(%ebx), %eax
addl $0x03, %eax
movl %eax, 0x0(%ebx)

//假定x的地址已经存放到了ebx,通过movl将这个地址的值加载到eax中
//对eax中的内容加3
//将eax中的值写回到内存中同一位置	

上述的代码很简单,再看这个进程的地址空间:

在这里插入图片描述
代码和数据都位于进程的地址空间,3条指令位于地址128,变量位于地址15kb,x的初始值为3000,执行上述3条指令,发生了如下内存访问:

从地址128获取指令
执行指令(从地址15kb加载数据)
从地址132获取指令
执行指令(此处相加发生在寄存器里,没有地址访问)
从地址135获取指令
执行指令(新值存入15kb处)

上述进程的地址空间从0到16kb,但是这是操作系统为它提供的假象,操作系统将这个进程放在了物理内存的其它位置,不是从地址0开始的,物理内存真实的情况可能是:
在这里插入图片描述
那么问题来了,怎样在内存中重定位这个进程?怎样提供一种虚拟地址从0地址开始的假象?

3.4 动态(基于硬件)重定位

地址转换最早称为基址加界限机制,也称动态重定位

具体说,每个CPU需要两个硬件寄存器,基址寄存器界限寄存器,这一组基址,界限寄存器可以让我们将地址空间放在物理内存的任意合法位置,同时又能确保进程只能访问自己的地址空间

(1) 基址寄存器

采用基址界限机制时,在编写和编译程序时假设地址空间从0开始,但是当程序真正开始运行时,操作系统会决定其在物理内存中的实际加载地址,并将起始地址记录在基址寄存器上

之后该进程的所有内存引用,都会通过如下方式从虚拟地址转换成物理地址:

物理地址 = 虚拟地址 + 基址地址(进程在物理内存中的起始地址)

进程中使用的内存都是虚拟地址,硬件接下来将虚拟地址加上基址寄存器中的内容,得到物理地址

对于上述示例的一条指令进行追踪:

128: movl 0x0(%ebx), %eax 

首先程序计数器(PC)被设置为128,当硬件需要执行这条指令时,它先将这个值加上基址寄存器中的32kb,得到实际的物理地址32896,再从32896这个物理地址获取指令并执行

将虚拟地址转换成物理地址,就是地址转换,硬件取得进程认为它要访问的地址,将它转换成数据实际位于的物理地址

(2) 界限寄存器

基址界限机制中另一部分是界限寄存器,界限寄存器提供了访问保护,在示例中,地址空间为16kb,界限寄存器被设置为16kb,如果进程想访问超过这个界限或者为负数的虚拟地址,CPU将触发异常,进程可能被终止

界限寄存器通常有两种使用方式:
1,界限寄存器记录地址空间的大小,硬件在将虚拟地址与基址寄存器内容求和前,先检查这个界限
2,界限寄存器存储地址空间结束的物理地址,硬件在转化虚拟地址到物理地址之后再检查这个界限

这两种方式本质是相同的,默认使用第一种

转换示例,某进程地址空间为4kb,被加载到开始地址为16kb的物理内存中:
在这里插入图片描述

通过基址加虚拟地址的方式,很容易得到物理地址,虚拟地址过大或为负数时,会导致异常

这种基址寄存器配合界限寄存器的硬件结构是芯片中的,有时将CPU负责地址转换的部分统称为内存管理单元 MMU

3.5 完成地址转换需要的硬件支持

在这里插入图片描述
为了完成地址转换,需要一些硬件支持

1,两种CPU模式,特权和用户模式
2,基址寄存器和界限寄存器,用户程序运行时,硬件会转换每个地址,硬件也必须检查地址是否可用,通过基址寄存器,界限寄存器和一些电路来完成
3,硬件应该提供一些特殊的指令,用于修改基址寄存器和界限寄存器中的值,允许操作系统在切换进程时改变它们,且这些指令必须在kernel模式下,如果用户程序可以更改基址寄存器和界限寄存器,那么这个程序就可以访问内存中的任意位置
4,用户程序非法访问内存时,CPU必须能产生异常,CPU应该阻止该应用程序的运行,并安排操作系统的对应异常处理程序终止该进程

3.6 虚拟内存时操作系统的新任务

为了支持动态重定位,硬件需要支持一些新功能,使得操作系统有了一些必须处理的新问题,硬件支持和操作系统管理结合到了一起,实现了一个简单的虚拟内存,即在一些关键时刻操作系统介入,以实现基址和界限的方式的虚拟内存

(1) 操作系统何时介入

1,在进程创建时,操作系统必须为进程的地址空间找到合适的物理内存空间
2,进程结束时,操作系统回收它的所有物理内存,给其它进程或者操作系统使用
3,切换进程时,由于只有一对基址寄存器和界限寄存器,所以操作系统要保存每个进程的基址寄存器和界限寄存器的值,当重新运行某进程时,也要正确恢复它的基址寄存器和界限寄存器
4,操作系统必须提供异常处理程序,当出现非法内存访问等异常时,操作系统能正确终止进程

(2) 空闲列表

操作系统必须记录哪些空闲的内存没有被使用,以便能够为进程分配内存,有很多不同的数据结构可以完成这项工作,最简单的是空闲列表,它就是一个列表,记录当前没有使用的物理内存的范围

3.7 小结

利用地址转换,操作系统可以控制进程的所有内存访问,确保访问在地址空间的界限内。这个技术的关键在于硬件支持,硬件快速的将所有内存访问操作中的虚拟地址转换为物理地址,所有这一切对于进程来说都是透明的,进程并不知道自己使用的物理内存已经被重定位

但使用基址加界限重定位有效率低下的问题,由于进程的堆区和栈区可能不是很大整块内存利用率不高,导致这块内存区域中大量的空间被浪费,这种浪费称为内部碎片,因此需要更复杂的机制,以便更好利用物理内存,避免内部碎片

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值