目录
3.段页式虚拟存储器 |
4.存储保护 |
总结 |
虚拟存储器机制与高速缓存Cache机制很类似,高速缓存Cache是缓存了内存中的数据,虚拟存储器是在内存中缓存了磁盘的数据。如果虚拟存储器中数据不存在,那么需要从磁盘上读取数据,然后放入内存。由于磁盘的速度要比内存慢10万倍,所以除了必要的情况,应尽量少的从磁盘反复读取数据。虚拟存储器采用全相联映射方式,所以每个虚拟地址可以映射到内存的任何一个空闲位置,因此与Cache类似,虚拟存储器必须有一种方法确定每个进程虚拟地址对应内存的位置或磁盘位置,其的映射方式有3种:分页式、分段式和段页式,下面一起来看看:
分页式存储器把内存和虚拟地址空间都划分成大小相等的页面,磁盘和内存按页面为单位交换信息。通常把虚拟地址空间的页面成为虚拟页/逻辑页(VP),内存中的页面成为页框/物理页(PP)。
操作系统在内存中给每个进程生成一个页表,页表中对应每个虚拟页都有一个表项,表项内容包括存放位置字段、装入位、修改位、替换控制位、存取权限位、禁止缓存位。它们的作用分别如下:
①存放位置字段:用来建立虚拟页和物理页之间的映射,用于虚拟地址到物理地址的转换
②装入位:也称有效位或存在位,为1表示磁盘数据已调入内存,位置字段指向物理页号。为0表示磁盘数据没有被调入内存,若位置字段为null则说明此位置空闲,若不为null则说明等待磁盘数据调入内存
③修改位:标识页面是否被修改过,在执行回写策略时根据此字段判断是否需要把数据写回磁盘
④替换控制位:标识页面使用情况,配合替换策略设置
⑤访问权限位:标识页面是可读可写、只读、只可执行,用于存储保护
⑥禁止缓存位:标识页面是否可以装入Cache,保证磁盘、内存、Cache数据一致性
页表、内存、磁盘的映射示意图如图1所示:
图1 映射示意图
例如,CPU执行一条指令需要访问数据,该数据正好在虚拟页VP1中,查询页表可知,VP1装入位为1,对应的物理页PP0,这时就可以通过地址转换部件把将虚拟地址转换为物理地址,然后访问PP0的数据。
如果数据在VP6中,VP6对应的装入位为0,表示页面缺失,发生“缺页”异常,需要操作系统进行“缺页”异常处理程序处理。“缺页”异常处理程序根据页表中VP6对应的存放位置字段,从磁盘中将数据读出,然后找一个空闲的物理页框存放,若内存中没有空闲的页框,则选择一个页面替换到磁盘上。
因为采用写回策略,所以页面淘汰时,需要根据修改位确定是否要写回磁盘。缺页处理过程中需要对页表进行相应的更新。缺页异常处理结束后,程序回到原来发生缺页的指令继续执行。
对于VP0和VP4,随着进程的动态执行,这些页面可能就会有了具体的数据。例如,当调用malloc函数时,堆区增长,新增的堆区正好与VP4对应,则操作系统就在磁盘上分配一个存储空间给VP4,同时把VP4页表项中的存放位置字段填上,对应的就是磁盘上的起始地址。之后便等待访问到这页数据时,再次执行上面的缺页异常流程,读取数据。
上面说完了页表、内存、磁盘的映射关系和数据读取流程,其中有个环节是需要把虚拟地址转换为真正的物理地址,转换工作由CPU中的存储器管理部件(MMU)完成,具体做法如下:
①虚拟地址分为两部分:高位为虚拟页号,低位为页内偏移地址
②物理地址也分为两部分:高位是物理页号,低位为页内便宜地址
③每个进程都有一个页表基址寄存器,存放该进程页表首地址
④根据页表基址寄存器找到对应的页表,由虚拟地址高位部分的虚拟页号为索引,找到页表项
⑤若装入位为1,则取出对应的物理页号,然后和虚拟页内地址拼接,得到司机的物理地址
⑥如装入位为0,则交给操作系统执行“缺页”处理
执行流程如图2所示:
图2 执行流程
从上述过程可以看出,每次访问内存都需要先查页表,然后根据规则找出物理地址,然后再访问实际的物理地址对应的数据。如果发生缺页,还要进行页表替换、页表修改等操作,访问内存的次数就更多。采用虚拟存储器,访问内存的次数增加了很多。那有没有什么办法减少访问次数,还能达到同样的效果呢?
答案是可以的,我们可以把页表中最活跃的几个页表项复制到高速缓存Cache中,这种高速缓存Cache中的页表项组成的页表称为快表(TLB)。
这样在进行地址转换时,先查看快表中是否命中,如果命中,则无需访问内存中的页表即可。通过这种方式可大大降低内存访问的次数,提升效率。
到此可以总结一下CPU访问数据的完整过程,如图3所示:
图3 CPU访问数据的完整过程
分页方式的虚拟存储器优点是页长固定,易管理,不存在碎片。但缺点是页长与程序的逻辑大小无关。例如,某个时刻一段代码有一部分在内存中,另外一部分则在磁盘上,不利于编程时的独立性,且给存储保护和存储共享造成了麻烦。所以又提出了分段式的存储器。把一段程序按照类别划分为段,例如方法、操作数、常数划分到不同的段中,每个段都是一组相对完整的逻辑信息。这样做的好处是可以按不同类型进行存储管理,也利于多个程序组合时,对同一段逻辑可以组合复用提供了便利。
分段的方式具体如下:
①虚拟地址由段号和段内地址组成
②内存按程序中的段划分,每个段在内存中的位置记录在段表中
③每个进程都有一个段表,每个段在段表中有一个段表项,标识段的位置、长度、访问权限、使用和装入情况
分段存储器把虚拟地址转换为物理地址流程如图4所示:
图4 虚拟地址与物理地址的转换
①段的划分与程序的自然分界相对应
②段的易于编译、管理、修改和保护,也便于多道程序共享
③段具有动态可变长度,允许自由调度以便利用内存空间
①段的长度不相同,起点和终点不固定,给内存分配带来麻烦
②容易在内存中留下零碎空间,导致空间浪费
段页式虚拟存储器是结合了分页式和分段式的优点,具体方式如下:
①程序按模块分段,段内再分页,用段表和页表进行两级定位管理
②段表中每个表项对应一个段,每个段表中包含一个指向该段页表起始位置以及控制信息和保护信息
③页表指明该段各页在内存中的位置和是否装入、修改等状态信息
④程序数据调入调出按页进行,又可以按段实现共享和保护。
缺点是地址映射过程需要多次查表。
每个用户进程有一个基号,标识用户进程,进程的段表起始地址存放在各自对应的基地寄存器中,格式如图5所示:
图5 用户进程格式
逻辑地址到物理地址的转换过程如图6所示:
图6 逻辑地址与物理地址的转换
为了避免多个程序运行时互相干扰,或者某个程序不合法地访问了其他程序的数据,应该对每个程序进行存储保护,保护的对象包括操作系统和用户程序。
(1)对操作系统存储保护主要是硬件提供支持:
①支持至少2种运行模式:管理模式、用户模式,操作系统在管理模式下管理各种功能,用户进程运行在用户模式下
②部分CPU状态只能由系统进程写,用户进程只能读:例如段表、页表首地址、TLB内容等
③提供让CPU在管理模式和用户模式之间切换的机制:通过“异常”处理让CPU从用户模式切换到管理模式,异常处理完成后通过“返回”指令让CPU回到用户模式
(2)对于用户进程的保护主要分为访问方式保护和存储区域保护:
①访问方式保护:检查“访问越权”,通过段表或页表的访问权限位控制,例如共享区域只可读不可写,程序段只可执行或只读,未授权区域不可访问等
②存储区域保护:检查“地址越界”,通过段页的起始地址和终止地址控制
以上就是虚拟存储器的实现方法介绍了。虚拟存储器是为了给用户提供更大的随机存取空间而采用的一种存储技术。它将内存与外存结合使用,好像有一个容量极大的内存储器,工作速度接近于主存,每位成本又与辅存相近,在整机形成多层次存储系统。目前已成为计算机系统中非常重要的部分。