
利用异常表处理Linux内核态缺页异常
发布时间:2006-10-23 12:10:21 来源:天极博客 网友评论 0 条1." 程序要访问的内核地址空间的内容不在内存中,先跳转到标号vmalloc_fault,如果当前访问的内容所对应的页目录项不在内存中,再跳转到标号no_context;
2. 缺页异常发生在中断或者内核线程中,跳转到标号no_context;
3. 程序在核心态运行时访问用户空间的数据,被访问的数据不在内存中
a) 出现异常的虚拟地址在进程的某个vma中,但是系统内存无法分配空闲页框(page frame),则先跳转到标号out_of_memory,再跳转到标号no_context;
b) 出现异常的虚拟地址不属于进程任一个vma,而且不属于堆栈扩展的范畴,则先跳转到标号bad_area,最终也是到达标号no_context。
从上面的这几种情况来看,我们关注的焦点最后集中到标号no_context处,即对函数search_exception_table的调用。这个函数的作用就是通过发生缺页异常的指令(regs->eip)在异常表(exception table)中寻找下一条可以继续运行的指令(fixup)。这里提到的异常表包含一些地址对,地址对中的前一个地址表示出现异常的指令的地址,后一个表示当前一个指令出现错误时,程序可以继续得以执行的修复地址。
如果这个查找操作成功的话,缺页异常处理程序将堆栈中的返回地址(regs->eip)修改成修复地址并返回,随后,发生异常的进程将按照fixup中安排好的指令继续执行下去。当然,如果无法找到与之匹配的修复地址,系统只有打印出出错信息并停止运作。
那么,这个所谓的修复地址又是如何生成的呢?是系统自动生成的吗?答案当然是否定的,这些修复指令都是编程人员通过as提供的扩展功能写进内核源码中的。下面我们就来分析一下其实现机制。
异常表的实现机制
笔者取include/asm-i386/uaccess.h中的宏定义__copy_user编写了一段程序作为例子加以讲解。
/* hello.c */ #include #include #define __copy_user(to,from,size) do { int __d0, __d1; __asm__ __volatile__ ( "0: rep; movsl/n" " movl %3,%0/n" "1: rep; movsb/n" "2:/n" ".section .fixup,/"ax/"/n" "3: lea 0(%3,%0,4),%0/n" " jmp 2b/n" ".previous/n" ".section __ex_table,/"a/"/n" " .align 4/n" " .long 0b,3b/n" " .long 1b,2b/n" ".previous" : "=&c"(size), "=&D" (__d0), "=&S" (__d1) : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from) : "memory"); } while (0) int main(void) { const char *string = "Hello, world!"; char buf[20]; unsigned long n, m; m = n = strlen(string); __copy_user(buf, string, n); buf[m] = '/0'; printf("%s/n", buf); exit(0); }先看看本程序的执行结果:
$ gcc hello.c -o hello $ ./hello Hello, world!
显然,这就是一个简单的"hello world"程序,那为什么要写得这么复杂呢?程序中的一大段汇编代码在内核中才能体现出其价值,笔者将其加入到上面的程序中,是为了后面的分析而准备的。
- 微软官方入门教程19:轻松掌握Vista系统的快
- 微软2008大冲击,预借Vista SP1力促Vista市
- 在收件箱中获得 Windows Vista 的最新更新
- 微软官方Vista入门教程全集19篇(Vista学院
- Windows Vista 的成功将势不可挡
- 快快抛弃Vista,拥抱XP SP3!你觉得呢?
- 浅谈Vista系统关闭虚拟内存与使用内存盘加速
- 嘿嘿,按下键盘上面的三个键,马上让你的Vi
- Windows Vista的盗版率只有Windows XP的一半
- 3DMark和PCMark Vantage新版将只支持Vista系
- Windows外衣Linux心 红旗桌面版详测
- 扮酷你的桌面 Linux超靓壁纸下载(多图)
- Linux安装流程
- 浅谈Linux的内核
- RedHat Linux9.0安装实例(1)
- ARM的嵌入式Linux移植体验之基本概念
- Linux安装要点
- 红旗Linux桌面版5.0BETA版OS
- 如何在大硬盘上安装Linux
- RealPlayer流媒体播放器Linux版
- Linux步入Unix的后尘-铁甲Linux出现
- Linux内核中的同步和互斥分析报告
- Linux操作系统文件系统的桌面应用
- Linux设备驱动编程之定时器
- 嵌入式Linux操作系统启动信息完全注释
- 在Linux操作系统中实现内部进程通信
- Linux大腕警告称开源软件存在安全问题
- Linux下双网卡绑定技术实现负载均衡
- 深入浅出Linux操作系统的优化和微调
- Linux下的中文显示和支持常见问题解答
- 大话G游 专题:手机病毒揭密
- ARP攻击防范与解决方案 路由故障处理手册
- Picasa中文版_Picasa教程 专题:清除流氓软件
- Firefox专题 seo搜索引擎优化专区
- 重装Windows必知的事情 装机之必备软件大行动
