第五章中断与异常.ppt

上传人:本田雅阁 文档编号:2560910 上传时间:2019-04-08 格式:PPT 页数:37 大小:774.01KB
返回 下载 相关 举报
第五章中断与异常.ppt_第1页
第1页 / 共37页
第五章中断与异常.ppt_第2页
第2页 / 共37页
第五章中断与异常.ppt_第3页
第3页 / 共37页
亲,该文档总共37页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《第五章中断与异常.ppt》由会员分享,可在线阅读,更多相关《第五章中断与异常.ppt(37页珍藏版)》请在三一文库上搜索。

1、第五章 中断与异常 中断的基本知识 中断描述符表的初始化 中断处理 中断的下半部处理机制 中断的应用时钟中断 中断控制的主要优点: CPU只有在I/O需要服务时才响应 外部中断: 外部设备所发出的I/O请求 内部中断: 也称之为“异常”,是为解决机器运行 时所出现的某些随机事件及编程方便 而出现的 中断常识 中断向量每个中断源都被分配一个8 位无符号整数作为类型码,即中断向量 中断的种类: 中断: 外部可屏蔽中断 外部非屏蔽中断 异常:不使用中断控制器,不能被屏蔽 故障 陷阱 外设可屏蔽中断 异常就是CPU内部出现的中断,即在CPU 执行特定指令时出现的非法情况。 非屏蔽中断就是计算机内部硬件

2、出错时 引起的异常情况 Intel把非屏蔽中断作为一种异常来处理 在CPU执行一个异常处理程序时,就不再 为其他异常或可屏蔽中断请求服务 中断描述符表 调用过程指令CALL : CALL 过程名 调用中断过程的指令INT INT 中断向量 中断返回指令IRET IRET 加载中断描述符表的指令LIDT LIDT 48位的伪伪描述符 初始化中断描述符表 IDT表项的设置通过_set_gaet()函数实现 调用该函数在IDT表中插入一个中断门: set_intr_gate(unsigned int n, void *addr) 调用该函数在IDT表中插入一个陷阱门: set_trap_gate(u

3、nsigned int n, void *addr) 调用该函数在IDT表中插入一个系统门: set_system_gate(unsigned int n, void *addr) 初始化陷阱门和系统门 中断门的设置是由init_IRQ( )函数中的一段 代码完成的 : 设置时必须跳过用于系统调用的向量0x80 中断处理程序的入口地址是一个数组 interrupt,数组中的每个元素是指向中断处 理函数的指针。 中断和异常的硬件处理 确定所发生中断或异常的向量i(在0255之间) 通过IDTR寄存器找到IDT表,读取IDT表第i项(或叫第i个 门) 分“段”级、“门”级两步进行有效性检查 检查是

4、否发生了特权级的变化 中断和异常处理中CPU的工作 SS ESP EFLAGS CS EIP ERROR CODE EFLAGS CS EIP ERROR CODE 堆 栈 增 长 方 向 中断发生前 夕的SS:ESP 返回地址 错误码 中断请求队列的建立 中断服务例程(Interrupt Service Routine ):每个中断请求都有自己 单独的中断服务例程 中断处理程序:共享同一条中断线 的所有中断请求有一个总的中断处 理程序 在Linux中,15条中断线对应15个中 断处理程序 中断线共享的数据结构 注册中断服务例程 int request_irq(unsigned int irq

5、, void (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) CPU从中断控制器的一个端口取得中断向量I 根据I从中断描述符表IDT中找到相应的中断门 从中断门获得中断处理程序的入口地址 判断是否要进行堆栈切换 调用do_IRQ()对所接收的中断进行应答 ,并禁 止这条中断线 调用handle_IRQ_event()来运行对应的中断 服务例程 从中断返回 中断服务例程在中断请求关闭的条 件下执行,避免嵌套使中断控制复 杂化 系统不能长时间

6、关中断运行,因此 内核应尽可能快的处理完中断请求 ,尽其所能把更多的处理向后推迟 内核把中断处处理分为为两部分:上半 部(top half)和下半部(bottom half),上半部内核立即执行,而 下半部留着稍后处理 小任务机制 struct tasklet_struct Struct tasklet_struct *next; unsigned long state; atomic_t count; void (*func) (unsigned long) ; unsigned long data; ; void tasklet_handler(unsigned long data) 小任

7、务不能睡眠,不能在小任务中使用信 号量或者其它产生阻塞的函数。但它运行 时可以响应中断 通过调用tasklet_schedule()函数并传递给它 相应的tasklet_struct指针,该小任务就会 被调度以便适当的时候执行: tasklet_schedule( unsigned long expires; unsigned long data; void (*function)(unsigned long); ; 定义定时器: struct timer_list my_timer; 初始化定时器: init_timer( 激活定时器: add_timer( 如果需要在定时器到期前停止定时器

8、, 可以使用del_timer()函数: del_timer( 定时器的执行与应用 timeout = 2 * HZ; /*1HZ等于100,因此为2000ms*/ set_current_state(TASK_INTERRUPTIBLE); remaining = schedule_timeout(timeout); 内核用定时器实现进程的延时,调用schedule_timeout( )函数,该函数执行 下列语句:struct timer_list timer; expire = timeout + jiffies; init_timer( timer.expires = expire; timer.data = (unsigned long) current; timer.function = process_timeout; add_timer( schedule( ); /* 进程被挂起直到定时器到期 */ del_timer_sync( timeout = expire - jiffies; return (timeout “ “内核之旅内核之旅 ” ”网站网站 http:/ 电子杂志栏目是关于内核研究和学习的资料 第八期“中断”,将向读者依次解释中断概念 ,解析Linux中的中断实现机理以及Linux下中 断如何被使用。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1