第九章 虚拟内存 第四、五节 虚拟内存作为内存管理和内存保护的工具

1、虚拟内存作为内存管理的工具

前面我们都是假设整个系统只有一个单独的页表。但是实际上操作系统为每个进程提供了一个独立的页表。也就是每个进程都有一个独立的虚拟地址空间。如下图所示
在这里插入图片描述

1、简化链接

独立的地址空间允许每个进程的内存映像使用相同的基本格式, 而不管代码和数据实际存放在物理内存的何处。对64 位地址空间, 代码段总是从虚拟地址0x400000开始。数据段跟在代码段之后, 中间有一段符合要求的对齐空白。栈占据用户进程地址空间最高的部分, 并向下生长。这样的一致性极大地简化了链接器的设计和实现, 允许链接器生成完全链接的可执行文件, 这些可执行文件是独立于物理内存中代码和数据的最终位置的。

2、简化加载

虚拟内存还使得容易向内存中加载可执行文件和共享对象文件。要把目标文件中.text和.data节加载到一个新创建的进程中, Linux加载器为代码和数据段分配虚拟页, 把它们标记为无效的(即未被缓存的,也就是分配页但是不把他们加载到DRAM中, 将页表条目指向目标文件中适当的位置(也就是磁盘中的适当地址)。加载器从不从磁盘到内存实际复制任何数据。都是按照按需页面调度,在每个页初次被引用时, 要么是CPU 取指令时引用的, 要么是一条正在执行的指令引用一个内存位置时引用的, 虚拟内存系统会按照需要自动地调入数据页。将一组连续的虚拟页映射到任意一个文件中的任意位置的表示法称作内存映射

3、 简化共享

一般而言, 每个进程都有自己私有的代码、数据、堆以及栈区域, 是不和其他进程共享的。但是对于操作系统内核代码和C标准库这种需要共享的数据和代码来说,虚拟内存提供了很好的帮助。操作系统
通过将不同进程中适当的虚拟页面映射到相同的物理页面, 从而安排多个进程共享这部分代码的一个副本, 而不是在每个进程中都包括单独的内核和C 标准库的副本。
在这里插入图片描述

4、简化内存分配

虚拟内存为向用户进程提供一个简单的分配额外内存的机制。当一个运行在用户进程中的程序要求额外的堆空间时(如调用malloc的结果), 操作系统分配一个适当数字(例如K)个连续的虚拟内存页面, 并且将它们映射到物理内存中任意位置的K个任意的物理页面。 由于页表工作的方式, 操作系统没有必要分配k个连续的物理内存页面。 页面可以随机地分散在物理内存中。

2、虚拟内存作为内存保护的工具

任何现代计算机系统必须为操作系统提供手段来控制对内存系统的访问。

  1. 不应该允许一个用户进程修改它的只读代码段
  2. 不应该允许它读或修改任何内核中的代码和数据结构
  3. 不应该允许它读或者写其他进程的私有内存
  4. 不允许它修改任何与其他进程共享的虚拟页面, 除非所有的共享者都显式地允许它这么做(通过调用明确的进程间通信系统调用)

那么如何使用虚拟内存进行控制呢?

1、利用地址翻译的访问控制

地址翻译机制可以以一种自然的方式扩展到提供更好的访问控制。因为每次CPU生成一个地址时, 地址翻译硬件都会读一个PTE, 所以通过在PTE上添加一些额外的许可位来控制对一个虚拟页面内容的访问十分简单。
在这里插入图片描述
如上图所示,每个PTE中已经添加了三个许可位。SUP位表示进程是否必须运行在内核(超级用户)模式下才能访问该页。运行在内核模式中的进程可以访问任何页面, 但是运行在用户模式中的进程只允许访问那些SUP为0的页面。READ位和WRITE位控制对页面的读和写访问。

如果一条指令违反了这些许可条件, 那么CPU就触发一个一般保护故障, 将控制传递给一个内核中的异常处理程序。Linux shell 一般将这种异常报告为"段错误(segmentation fault)"。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值