深入理解Linux内核个人小结4---中断和异常
2012-10-01 10:00
621 查看
一. 中断和异常综述
中断分为两种:
同步中断:又称之为异常,是不可屏蔽中断。
异步中断: 即通常的中断,部分可屏蔽。且异常有对应的出错码。
内核控制路径: 中断发生时正在运行的程序在内核态的执行。
中断向量:8位无符号整数,用来标识中断和异常。其中非屏蔽的中断和异常对应的中断向量是固定的。而可屏蔽的中断向量可通过PIC(可编程中断控制器)进行编程来改变。其中中断向量的前32个被异常所占用(0~19已用,20~31保留),128号为系统调用。
IRQ与PIC的交互过程:
1.PIC监视IRQ线,检查产生的信号,若同时在两条以上的IRQ线上产生信号则选择编号较小的。
2.PIC将接受的信号转换成中断向量,并将其放在I/O端口,产生一个INTR中断,待CPU读取中断向量后清INTR中断;然后返回第一步。
中断禁止与中断屏蔽的区别:
中断禁止可选局部且中断不会丢失,而屏蔽则是全局的期间会导致中断丢失。
二. 中断和异常的硬件处理
中断描述符表:IDT 类似GDT都是8个字节。 基址存放于寄存器IDTR中。共三种:任务们描述符,中断门描述符,陷阱门描述符。
硬件处理过程:
1. 确定对应的中断向量i
2, 经IDTR 读取IDT中的第i项,从中可得到相应的中断(异常)处理程序的段基址及偏移量。
3. 相关的权限检查
4. 保存相应的寄存器的值到堆栈 如 cs/eip,若是异常还应当将出错码压入到堆栈中,将处理程序的基址/偏移量压入cs/eip中,进行处理
5. 处理结束返回,弹出出错码;将事先保存在堆栈的cs/eip的值放入cs/eip寄存器,继续开始正常运行。
中断与异常嵌套
中断可以嵌套,但其间不能发生进程切换。因嵌套时相应信息都保存在内核态堆栈,若进程切换将导致相应内容被换出内核。
异常最多发生两层的嵌套,(因异常大都发生在用户态),由于缺页中断发生在内核态,故最多可发生两层嵌套且最后一层为缺页中断。
三. 异常和终端的Linux下的处理
异常处理: 异常发生时,CPU或其他产生一个异常,对应的异常处理程序(相关工作有硬件进行处理)向当前进程发送一个信号,此进程采取下列步骤进行处理
1. 内核态堆栈中保存大多数寄存器的值。
2. 用高级C语言函数处理异常。
3.ret_from_exception()函数跳出异常。
中断处理:
1. 在内核态堆栈中保存IRQ的值及寄存器的内容
2. 给正在为IRQ服务的PIC发送一个应答,允许PIC进一步发出中断
3. 执行此IRQ的所有设备的中断服务例程(ISR)
4. ret_from_intr()函数跳出中断。
软中断,tasklet与工作队列:
为了让中断处理的更快,同时要完成相应的全部工作。根据具体没内容将中断分为两部分:上半部分(中断处理部分)和下半部分(推后处理部分)。上半部分需要立 即 执行并且有严格的时间限制,这些工作是在其他所有中断被禁止是完成的,剩余部分推迟到下半部分,下半部分的任务是执行与中断处理密切相关但中断处理程序本身 不执行的工作。在Linux2.6内核中存在三种不同形式的下半部分实现机制: 软中断,tasklet和工作队列。
软中断:
编译期间静态分配的,最多有32个软中断,软中断之间不会抢占,唯一可抢占软中断的是中断处理程序。
tasklet:基于两种软中断实现的 HI_SOFIRQ和TASKLET_SOFTIRQ,无数量限制可动态增加,同类型不可并发执行,而不同种类可以并发执行。
工作队列:由内核线程去执行,允许重新进行带哦度,如可以睡眠阻塞等。
中断分为两种:
同步中断:又称之为异常,是不可屏蔽中断。
异步中断: 即通常的中断,部分可屏蔽。且异常有对应的出错码。
内核控制路径: 中断发生时正在运行的程序在内核态的执行。
中断向量:8位无符号整数,用来标识中断和异常。其中非屏蔽的中断和异常对应的中断向量是固定的。而可屏蔽的中断向量可通过PIC(可编程中断控制器)进行编程来改变。其中中断向量的前32个被异常所占用(0~19已用,20~31保留),128号为系统调用。
IRQ与PIC的交互过程:
1.PIC监视IRQ线,检查产生的信号,若同时在两条以上的IRQ线上产生信号则选择编号较小的。
2.PIC将接受的信号转换成中断向量,并将其放在I/O端口,产生一个INTR中断,待CPU读取中断向量后清INTR中断;然后返回第一步。
中断禁止与中断屏蔽的区别:
中断禁止可选局部且中断不会丢失,而屏蔽则是全局的期间会导致中断丢失。
二. 中断和异常的硬件处理
中断描述符表:IDT 类似GDT都是8个字节。 基址存放于寄存器IDTR中。共三种:任务们描述符,中断门描述符,陷阱门描述符。
硬件处理过程:
1. 确定对应的中断向量i
2, 经IDTR 读取IDT中的第i项,从中可得到相应的中断(异常)处理程序的段基址及偏移量。
3. 相关的权限检查
4. 保存相应的寄存器的值到堆栈 如 cs/eip,若是异常还应当将出错码压入到堆栈中,将处理程序的基址/偏移量压入cs/eip中,进行处理
5. 处理结束返回,弹出出错码;将事先保存在堆栈的cs/eip的值放入cs/eip寄存器,继续开始正常运行。
中断与异常嵌套
中断可以嵌套,但其间不能发生进程切换。因嵌套时相应信息都保存在内核态堆栈,若进程切换将导致相应内容被换出内核。
异常最多发生两层的嵌套,(因异常大都发生在用户态),由于缺页中断发生在内核态,故最多可发生两层嵌套且最后一层为缺页中断。
三. 异常和终端的Linux下的处理
异常处理: 异常发生时,CPU或其他产生一个异常,对应的异常处理程序(相关工作有硬件进行处理)向当前进程发送一个信号,此进程采取下列步骤进行处理
1. 内核态堆栈中保存大多数寄存器的值。
2. 用高级C语言函数处理异常。
3.ret_from_exception()函数跳出异常。
中断处理:
1. 在内核态堆栈中保存IRQ的值及寄存器的内容
2. 给正在为IRQ服务的PIC发送一个应答,允许PIC进一步发出中断
3. 执行此IRQ的所有设备的中断服务例程(ISR)
4. ret_from_intr()函数跳出中断。
软中断,tasklet与工作队列:
为了让中断处理的更快,同时要完成相应的全部工作。根据具体没内容将中断分为两部分:上半部分(中断处理部分)和下半部分(推后处理部分)。上半部分需要立 即 执行并且有严格的时间限制,这些工作是在其他所有中断被禁止是完成的,剩余部分推迟到下半部分,下半部分的任务是执行与中断处理密切相关但中断处理程序本身 不执行的工作。在Linux2.6内核中存在三种不同形式的下半部分实现机制: 软中断,tasklet和工作队列。
软中断:
编译期间静态分配的,最多有32个软中断,软中断之间不会抢占,唯一可抢占软中断的是中断处理程序。
tasklet:基于两种软中断实现的 HI_SOFIRQ和TASKLET_SOFTIRQ,无数量限制可动态增加,同类型不可并发执行,而不同种类可以并发执行。
工作队列:由内核线程去执行,允许重新进行带哦度,如可以睡眠阻塞等。
相关文章推荐
- 深入理解Linux内核个人小结9---进程地址空间
- 深入理解Linux内核个人小结5---内核同步
- 深入理解Linux内核个人小结10---系统调用
- 深入理解Linux内核个人小结12---虚拟文件系统
- 深入理解Linux内核(4)---中断和异常(x86平台)
- 深入理解Linux内核(4)---中断和异常(x86平台)
- 深入理解Linux内核个人小结3--进程
- 深入理解Linux内核个人小结8---内存区管理
- 深入理解linux内核——中断和异常(下——多核&可延迟中断)
- 深入理解Linux内核个人小结1---绪论
- 深入理解Linux内核-中断和异常
- 深入理解Linux内核个人小结2---内存寻址
- 读深入理解Linux内核 (第4章 中断和例外)
- 深入理解Linux 内核 chp 2 内存寻址
- 一步步理解Linux之中断和异常
- 好书推荐——关于学习Linux的经典书籍 (深入理解Linux内核、Linux设备驱动程序等)
- Linux编程细节5-内核-中断异常
- linux 中断,异常与抢占内核
- 关于学习Linux的经典书籍 (深入理解Linux内核、Linux设备驱动程序等)
- 深入剖析Linux中断机制之三---Linux对异常和中断的处理