有关实现的问题
一 分页的问题
操作系统会在下面的四段时间里做与分页相关的工作
进程创建的时候,进程执行的时候,发生缺页中断的时候,进程终止的时候
进程在创建的时候必须确定程序和数据有多大,并为他们创建一个页表,操作系统要为页表分配内存空间并且为他们初始化,当一个进程启动的时候必须为该进程重置MMU以及TLB,新进程页表必须为当前页表,通常可以复制该页表,或者说是将一个指向它的指针放进硬件寄存器中,初始化的时候可以将进程的一部分页面放进内存中以减少缺页中断。
进程在运行过程中页表必须在内存中,但是当它被交换出磁盘中的时候可以不再内存中,操作系统必须为进程在磁盘交换区中准备空间,以便进程被交换出内存的时候在磁盘中有地方放置该进程。
另外操作系统还要用程序正文和数据段初始化交换区,以便发生缺页中断的时候能够及时将页面调入内存中,最后操作系统必须把页表和交换区的信息保存在进程表中。
当发生缺页中断的时候,需要读取硬件寄存器来确定那个页面发生了中断,然后确定在磁盘中的位置。接下来还要找到合适的叶框,然后置换老的页面,将新页面装进页框中,最后还要备份程序计数器,指向引起中断的指令,并重新执行该指令。
程序退出的时候,必须释放页表和页框以及页面在磁盘交换区上占用的空间。
二 缺页中断的处理
1 硬件陷入内核,将程序计数器保存在堆栈中。
2 调用一段汇编代码将通用寄存器等易失信息保存在堆栈中。
3 查找所需页面的虚拟地址,一般硬件寄存器中包含了这个地址。
4 得到虚拟地址之后,操作系统检查这个地址是否存在,并检查读取保护是否一致,如果不一致则杀死该进程,如果没有错误则检查是否有空闲页框,如果没有空闲页框则调用页面置换程序选择一个将要被置换出去的页框。
5 检查这个页框是否为脏,如果该页框已经被更改过了,那么将这个页面写入磁盘中并且该进程发生中断。让其他进程运行,并将这个页框标记为忙以免被其他程序占用。
6 一旦页框干净后则将计算该页面在磁盘中的地址,操作系统将这个页面装入内存,该页面装入后,产生缺页中断的进程仍然被挂起着
7 当磁盘中断发生的时候,表明这个页面已经被装入内存中了,页表也更新可以反映内存中叶框的位置了,页框也被标记为正常状态,
8 恢复发生缺页中断时的状态,读取程序计数器中的指令,程序技术器指向这条指令
9 调度引发缺页中断的进程,操作系统返回调用它的汇编语言例程
10 该历程恢复堆栈中的寄存器和其他信息,返回到用户空间继续执行,就好像没有发生过一样
三 后备存储
这里主要讨论页面被置换出内存的时候会存储在哪里
一种方式是在磁盘的文件系统中设置交换去,每个进程启动的时候,操作系统为每个进程分配与进程大小相同的交换区,当有页面要写入磁盘的时候,就可以使用交换区的起始地址加上偏移地址
交换区其实是进程映像保存的地方。这种模式有一个问题就是程序在运行过程中数据或者堆栈会增长,所以说要允许交换区在磁盘上多出一部分
还有一种方式是将进程全部交换入内存中,在需要换出的时候再将页面换出到磁盘中,这种方式的话需要在内存中保留一张表,记录每个页面在磁盘中的位置。
有时候磁盘不能够保证分配那么大的分区,所以说要可以利用文件系统中一个较大的事先定位的文件,比如说windows中因为程序代码段本身就是来自可执行文件,所以说这样的话就可以使用可执行文件作为交换区,
浙公网安备 33010602011771号