超清壁纸1920x1080:缺页异常

来源:百度文库 编辑:九乡新闻网 时间:2024/05/09 12:20:03

缺页异常总结 - [软件与系统]

Tag:Kernel

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://feizf.blogbus.com/logs/19002441.html

产生页面异常的原因:
(1).目标页面不存在(页表项全0,即该线性地址与物理地址尚未建立映射或者已经撤销);
(2).相应的物理页面不在内存中(页表项非空,但P标志=0,比如在swap分区或磁盘文件上);
(3).访问权限不符合(此时页表项P标志=1,比如企图写只读页面).

当出现上面情况之一,那么就会产生页面page fault异常。产生异常的线性地址存储在CR2中,所以在do_page_fault()中首先将这个地址读进来,接着:

一. 看该线性页表项是否为全0.不是全0说明映射已经建立,只是物理页面在交换设备中,那么就从交换设备上把页面换进来. 如果页表项全0说明映射还没建立,那么进入第二步.

二. 最一般的情况,检查目标线性地址是否是无效的.

如果目标地址(>3GB),那么就要看是否本次page fault异常是内核态引起的,是则跳转执行特定代码,不是就说明线性地址无效.

如果目标地址在进程地址空间(<3GB)并且不是在中断中,那么用find_vma()从所属进程所用的线性区链表里找到"结束地址大于该地址的第一个线性区vma",结果:

(1)如果找不到上述线性区vma,则线性地址越界了,跳到bad_area, 最终segment fault.

(2)如果找到了上述线性区vma,但目标地址不在找到的vma区间内(即 addrstart),那么说明本次异常要么是为了扩展堆栈expand_stack(满足:找到的vma设置VM_GROWSDOWN标志,且addr+32>regs->esp),要么也是无效地址跳到bad_area,最终segment fault.

(3)如果找到了上述线性区vma,并且目标地址在vma区间内,那么跳转到good_area. 在good_area检查满足访问权限(读/写/执行)后,就handle_mm_fault()最终handle_pte_fault()决定来请求调页(demand paging)或写时复制(COW).这才是处理缺页异常的核心,下面集中讲这一点。

三. 上面handle_pte_fault()做得事情分成2种情况:

(1)目标地址对应的页表项Present标志=0,也就是由最开头产生页面异常的原因(1)和(2)。处理办法:对于(1)目标页面根本就不存在,那么do_no_page()分配一个物理页面并建立映射; 对于(2)目标页面不在内存中,那么就从磁盘文件或交换分区中换入内存,分别对应do_file_page()和do_swap_page().  

(2)目标地址对应的页表项Present标志=1,也就是由最开头产生页面异常的原因(3),处理办法: 分配一个新页框,实现写时复制(COW).