1 介绍
计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。
计算机系统u燃机系统结构的层次结构设计如下:
每个层次之间都需要相互通信,既然需要通信就必须有一个通信的协议,也就是接口。一般接口的下面那层就是接口的提供者,接口由它定义;接口的上层就是接口的使用者,它使用该接口来实现需要的功能。
例如,从整个层次结构来看,开发工具与应用程序属于同一层次,它们都是要运行库提供的接口,也就是应用程序编程接口。应用程序接口的提供者就是运行库,什么样的运行库提供什么样的API。而对于操作系统,运行库是操作系统提供的系统调用接口的使用者,操作系统是提供者。而操作系统内核层对于硬件层来说是硬件接口的使用者,而硬件是接口的定义者,硬件的接口定义决定了操作系统内核,具体来说就是驱动程序如何使用操作硬件,如何与硬件通信。
2 操作系统做什么
操作系统的一个功能是提供抽象的接口,另一个主要功能是管理硬件资源。
一个计算机的资源主要分CPU、存储器(包括内存和磁盘)和I/O设备。
2.1 内存不够怎么办
在早期的计算机,程序是直接运行在物理内存上的,也就是说,程序在运行时所访问的地址是物理地址。当然,如果一个计算机同时只运行一个程序,那么只要程序要求的内存空间不要超过物理内存的大小,就不会有问题。这样明显的一个问题是当有多个程序要运行?
缺点:
- 地址空间不隔离,所有程序都直接访问物理内存,程序锁使用的内存空间不是相互隔离的。
- 内存使用效率低,由于没有有效的管理,通常一个程序需要执行时,需要将整个程序都调入内存。
- 程序运行的地址不确定。因此程序每次都需要装入运行,我们从内存中给它分配内存,但是分配的地址是不确定的。
解决这些问题的办法是,增加中间层,即使用一种间接访问地址的方法。我们把程序的地址看做是一种虚拟地址,然后通过某些映射的方法,将虚拟地址转换为物理地址。这样保证任意一个程序访问的地址空间与另一个程序相互不重叠,以达到地址空间隔离。
2.1.2 关于隔离
虚拟地址空间是虚拟的、人们想象出来的地址空间,其实它并不存在,每个进程都有自己独立的虚拟地址空间,而且每个进程都只能访问自己的地址空间,这样就有效地做到了进程的隔离。
2.1.3 分段
最开始人们使用的是一种叫做分段的方法,基本思路是把一段程序所需要的内存空间大小的虚拟空间映射到某个地址空间。但是这样做只能解决第一个和第三个问题,并没有解决第二个问题,即内存效率的问题。分段对内存区域的映射还是按照程序为单位,如果内存不足,被换入换出到磁盘的都是整个程序,这样势必会造成大量的磁盘访问操作,主要是分段的粒度比较大。因为根据程序的局部性原理,在某个时间,它只会访问到一个小部分数据,也就是说,程序的很多数据都不会用的,于是想到粒度更小的分页。
2.1.4 分页
分页的基本方法是把地址空间分成固定大小的页,每一页的大小由硬件决定,或硬件支持多种大小的页,由操作系统选择决定页的大小。
例如,如下图所示,每个虚拟空间有8个页,每页大小为1KB,那么虚拟地址空间就是8KB。假设有6KB的内存,那么物理空间其实真正有效的只是前6KB。
那么,我们把进程的虚拟地址空间按页分割,把常用的数据和代码页装载到内存中,把不常用的代码和数据保存在磁盘里,当需要用到的时候再把它从磁盘取出来即可。我们假设有两个进程process1和process2,它们进程中的部分虚拟页面被映射到了物理页面,比如VP0、VP1和VP7映射到PP0、PP2、和PP3;而有部分页面却在磁盘中,比如VP2和VP3在磁盘DP0和DP1中;另外还有一个页面如VP4、VP5和VP6可能尚未被用或访问到,它们暂时处于未使用的状态。在这里,我们把虚拟空间的页称为虚拟页(VP),把物理内存中的页叫做物理页(PP),把磁盘中的页叫做磁盘页(DP)。
process1的VP2和VP3不在内存中,但是当访问这两页的时候,硬件会捕获到这个消息,就是所谓的页错误,然后操作系统接管进程,负责将VP2和VP3从磁盘中读出来并装入内存,然后将内存中的这两页与VP2和VP3之间建立映射关系,更新页表。
但是如果访问process1的VP5和VP6,则会出现段错误(由于这两页还没有映射)。
保护也是也映射的目的之一,简单地说就是每个页可以设置权限属性,谁可以修改,谁可以访问等。
虚拟存储的实现需要硬件的支持,对于不同的CPU来说是不同的,但是几乎所有的硬件都采用一个叫做MMU的部件来进行也映射。如图所示:
在页模式下,CPU发出的是virtual Address,即我们看到的是虚拟地址。经过MMU转换为physical Address。