1) 硬件陷入内核,在内核堆栈中保存程序计让含档数器。大多数机器将当前指令的各种状态信息保存在特殊的CPU寄存器中。
2) 启动一个汇编代码例程保存通用寄存器和其他易失的信息,以免被 *** 作系统破坏。这个例程将 *** 作系统作为一个函数来调用。
3) 当 *** 作系统发现一个缺页中断时,尝试发现需要哪个虚拟页面。通常一个硬件寄存器包含了这一信息,如果没有的话, *** 作系统必须检索程序计数器,取出这条指令,用软件分析这条指令,看看它在缺页中断时正在做什么。
4) 一旦知道了发生缺页中断的虚拟地址, *** 作系统检查这个地址是否有效,并检查存取与保护是否一致。如果不一致,向进程发出一个信号或杀掉该进程。如果地址有效且没有保护错误发生,系统则检查是否有空闲页框。如果没有空闲页框,执行页面置换算法寻找一个页面来淘汰。
5) 如果选择的页框“脏”了,安排该页写回磁盘,并发生一次上下文切换,挂起产生缺页中断的进程,让其他进程运行直至磁盘传输结束。无论如何,该页框被标记为忙,以免因为其他原因而被其他进程占用。
6) 一旦页框“干净”后(无论是立刻还是在写回磁盘后), *** 作系统查找所需页面在磁盘上的地址,通过磁盘 *** 作将其装入。该页面老旦被装入后,产生缺页中断的进程仍然被挂起,并且如果有其他可运行的用户进程,则选择另一个用户进程运行。
7) 当磁盘中断发生时,表明该页已经被装入,页表已经更新可以反映它的位置,页框也被标记为正常状态。
8) 恢复发生缺页中断指令以前的状态,程序计数器重新指向这条指令。
9) 调度引发缺页中断的进程, *** 作系统返回调用它的汇编语言例程。
10) 该例程恢复寄存器和其他状态信坦乱息
malloc()和mmap()等内存分配函数,在分配时 只是建立了进程虚拟地址空间,并没有分配虚拟唤哗内存对应的物理内存。 当进程访问这些没有建立映射关系的虚拟内存时,处理器自动触发一个缺页异常。
缺页中断:在请求分页系统中,可以通过查询页表中的状态位来确定所要访问的页面是否存在于内存中。每当 所要访问的页面不在内存时 ,会产生一次缺页中断,此时 *** 作系统会根据页表中的外存地址在外存中找到所缺的一页,将其调入内存。
缺页本身是一种中断,与一般的中断一样,需要经过4个处理步骤:
1、保护CPU现场
2、分析中断原因
3、转入缺页中断处理程序进行处理
4、恢复CPU现场,继续执行
但是缺页中断是由于所要访问的页面不存在于内存时,由硬件所产生的一种特殊的中断,因此,与一般的中断存在区别:
1、在指令执行期间产生和处理缺页中断信号
2、一条指令在执行期间,可能产生多次缺页中断
3、缺页中断返回是,执行产生中断的一条指令,而一般的中断返回是,执行下一条指令。
当访问一丛宽个内存中不存在的页,并且内存已满 ,则需要从内存中调出一个页或将数据送至磁盘对换区,替换一个页,这种渗链亮现象叫做缺页置换。当前 *** 作系统最常采用的缺页置换算法如下:
当前最常采用的就是LRU算法。
do_page_fault是缺页中断的核心函数,主要工作交给__do_page_fault处理,然后进行一些异常处理__do_kernel_fault和__do_user_fault。
__do_page_fault查找合适的vma,然后主要工作交给handle_mm_fault;handle_mm_fault的核心又是handle_pte_fault。
handle_pte_fault中根据也是否存在分为两类:do_fault( 文件映射缺页中断 )、do_anonymous_page( 匿名页面缺页中断 )、do_swap_page()和do_wp_page( 写时复制 )。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)