|
c024ac80 c0106de3 c0106de6 c010718b c021786c
|
上面的vmlinux就是编译内核所生成的内核可执行程序。和本文给出的例子相比,唯一的不同就是此时的地址对中的异常指令地址和修复地址都是内核空间的虚拟地址。也正是在内核中,异常表才真正发挥着它应有的作用。
总结
下面我对前面所讲述的内容做一个归纳,希望读者能够对内核缺页异常处理有一个清楚的认识:
进程访问内核地址空间的"非法"地址c010718b,存储管理部件(MMU)产生一个缺页异常;CPU调用函数do_page_fault;do_page_fault调用函数search_exception_table(regs->eip == c010718b);search_exception_table在异常表中查找地址c010718b,并返回地址对中的修复地址c021786c; do_page_fault把堆栈中的返回地址eip修改成c021786c并返回;代码按照缺页异常处理程序的返回地址继续执行,也就是从c021786c开始继续执行。
把验证用户空间地址信息"合法"性的工作交给硬件来完成(通过缺页异常的方式)其实就是一种Lazy Computation,也就是等到真正出现缺页异常的时候才进行处理。通过本文的分析可以看出,这种方法与本文前面所提到的通过verify_area来验证的方法相比,较好的避免了系统在无用验证上的开销,能够有效的提高系统的性能。此外,在分析源码的过程中读者会发现,异常表并不仅仅用在缺页异常处理程序中,在通用保护(General Protection)异常等地方,也同样用到了这一技术。
由此可见,异常表是一种广泛应用于Linux内核中的异常处理方法。在系统软件的设计中,异常表也应该成为一种提高系统稳定性的重要手段。
共6页: 上一页 [1] [2] [3] [4] [5] 6 下一页
|