内存管理-缺页异常
首先解释一下什么叫做异常:
x86 将中断分成两个部分,外部中断叫做中断,内部中断叫做异常;中断是由异步的外部事件引起的,异常是由CPU内部发起的,在执行指令期间检测到不正常的或者非法的条件引起的,比如除0操作。
根据引起异常的程序是否可以被恢复和恢复点不同,把异常分为fault, trap, abort; 缺页异常就属于trap;
缺页异常的初始化是在内核启动时就开始的,
start_kernel->setup_arch->early_trap_init->set_intr_gate(X86_TRAP_PF, &page_fault)
在中断向量表中注册page_fault服务例程;X86_TRAP_PF值为14,
在entry_32.S 汇编代码中有page_fault服务例程,获取当前进程堆栈,获取错误码,然后调用do_page_fault进行处理;
CPU通过地址总线可以访问连接在地址总线上的外设,包括物理内存,IO设备等,从CPU发出的访问地址是虚拟地址,由MMU将虚拟地址转换成物理地址,再从地址总线上发出,MMU上没有一个虚拟地址和物理地址的映射时(还有其他情况),MMU通知CPU产生一个缺页异常。
缺页异常的基本处理逻辑:
1、address = read_cr2(); 获取缺页异常的虚拟地址;
2、unlikely(fault_in_kernel_space(address)) (缺页一般不会发生在内核地址空间,所以用unlikely)
执行vmalloc_fault ->如果是非连续内存区地址,进行内核页表修正
如果是连续内存区,地址是错误的参数,向应用层进程发送SEGV信号,否则产生Oops
3、如果缺页发生在用户空间,内核通过address获取线性地址所在的线性区
vma = find_vma(tsk->mm, address)
如果vma为NULL,说明这个地址是错误地址,那么内核发送SEGV信号给当前进程,如果是正确的地址会进行写权限的检查,如果都匹配,则进行handle_mm_fault,分配一个页框
4、handle_mm_fault 分配新的页目录和页表,然后通过handle_pte_fault处理页框
5、对没有被进程访问过的而且不是文件映射的页,执行do_no_page,对文件映射执行do_file_page,对交换出去的页执行do_swap_page
6、do_no_page 调用do_anonymous_page获得一个新页框
阅读(2157) | 评论(0) | 转发(0) |