《linux内核完全剖析》笔记02-中断处理
来源:互联网 发布:在线网络理财规划 编辑:程序博客网 时间:2024/05/17 12:03
1. 从硬件故障中断处理理解
要理解中断系统从理解一段代码开始
no_error_code: xchgl %eax,(%esp) #将eax的内容和esp所指堆栈的内容相交换 pushl %ebx pushl %ecx pushl %edx pushl %edi pushl %esi pushl %ebp push %ds push %es push %fs pushl $0 # 第二个参数 lea 44(%esp),%edx pushl %edx #第一个参数 movl $0x10,%edx #转到内核态 mov %dx,%ds mov %dx,%es mov %dx,%fs call *%eax #调用中断处理函数 addl $8,%esp pop %fs pop %es pop %ds popl %ebp popl %esi popl %edi popl %edx popl %ecx popl %ebx popl %eax iret #返回被中断程序
以上内容是linux/kernel/asm.s中实现中断调用最核心的代码
完整的中断调用程序如下
_divide_error: pushl $_do_divide_error jmp no_error_code
_divide_error是代表在内核中的一个地址,在汇编中代表定义了标号,在c语言中代表void divide_error(void);函数
然后我们再来看中断的初始化操作linux/kernel/traps.c中的trap_init(void)函数的实现
void trap_init(void){ int i; set_trap_gate(0,÷_error); ...}
set_trap_gate(0,÷_error)就是将中断向量表中第1项的中断处理程序设置为divide_error,也就是asm.s中定义的_divide_error标号,而在_divide_error中push $_do_divide_error变量是一个C函数,这个函数在traps.c中定义
void do_divide_error(long esp, long error_code){ die("divide error",esp,error_code);}
以上设置中断处理函数要特别注意中断向量号,上面为0,是什么意思?
这些就是Intel保留的中断向量号的定义,也就是从CPU发出的俗成约定,这个地方我理解了很久:!
以上内容就是大部分硬件故障的中断处理函数的处理过程,剩下的部分就是对8259A中断控制器的中断响应处理和系统调用(俗称软中断)
2. 8259A中断处理
理解8259A的中断处理过程,从理解一段代码开始:
mov al,#0x11 #(ICW1设置)中断请求边沿触发多片8259级联并最需发送ICW4 out #0x20,al ! send it to 8259A-1 .word 0x00eb,0x00eb #0x00eb跳转到下一句的机器码 out #0xA0,al ! and to 8259A-2 .word 0x00eb,0x00eb mov al,#0x20 #(ICW2设置)主片中断号范围从0x20开始 out #0x21,al .word 0x00eb,0x00eb mov al,#0x28 #从片中断号范围从0x28开始 out #0xA1,al .word 0x00eb,0x00eb mov al,#0x04 #(ICW3设置)设置主芯片 out #0x21,al .word 0x00eb,0x00eb mov al,#0x02 #设置从芯片 out #0xA1,al .word 0x00eb,0x00eb mov al,#0x01 #(ICW4设置):普通EOI,非缓冲切需发送指令来复位的模式 out #0x21,al .word 0x00eb,0x00eb out #0xA1,al #8259A中断控制器初始化结束 .word 0x00eb,0x00eb mov al,#0xFF #屏蔽所有中断请求 out #0x21,al .word 0x00eb,0x00eb out #0xA1,al
读取以上代码有困难的话,需要复习一下8259A中断控制器的相关知识,这是微机接口原理的主要内容,不过阅读上面代码的重点是告诉我们8259的中断向量是从0x20开始的,要记住这一点,不然时钟中断,硬盘中断等的中断向量号是怎么来的,你就不从知晓,可以参考一下列表:
现在来看具体的中断处理向量的设置,它们分散在不同的地方
1. 时钟中断向量设置
timer_interrupt这就是操作系统的心跳函数
linux/kernel/sched.c
void sched_init(void){ ... set_intr_gate(0x20,&timer_interrupt); ...}
2. 硬盘中断向量设置
linux/kernel/blk_drv/hd.c
void hd_init(void){ ... set_intr_gate(0x2E,&hd_interrupt); ...}
3. 键盘中断向量设置
linux/kernel/chr_drv/console.c
void con_init(void){ ... set_trap_gate(0x21,&keyboard_interrupt); ...}
想象一下,如果没有中断,那操作系统不是会一直要去查询各种设备的状态而忙死么
3. 系统调用(软中断)
- 《linux内核完全剖析》笔记02-中断处理
- <<Linux内核完全剖析 --基于0.12内核>>学习笔记 第4章 80x86保护模式及其编程 4.6 中断和异常处理
- linux内核完全剖析之(2)中断和异常处理
- 《Linux内核完全剖析》阅读笔记
- 《Linux内核完全剖析》阅读笔记
- 《Linux内核完全剖析》阅读笔记
- 《Linux内核完全剖析》阅读笔记
- linux内核分析笔记----中断和中断处理程序
- linux内核分析笔记----中断和中断处理程序
- linux内核分析笔记----中断和中断处理程序
- linux内核分析笔记----中断和中断处理程序
- linux内核分析笔记----中断和中断处理程序
- Linux内核中断处理
- linux内核中断处理
- linux内核完全剖析0.12笔记--第一章,概述
- 《linux 内核完全剖析》 笔记 CODE_SPACE 宏定义分析
- 《linux 内核完全剖析》 signal.c 代码分析笔记
- 《linux 内核完全剖析》 exit.c 代码分析笔记
- Python中在for循环中嵌套使用if和else语句的技巧
- 《Spring Boot官方文档》开始Spring Boot
- 字典树(Trie)的简单实现
- 2.Oracle:Oracle中dual表的用途介绍(转载)
- 介绍一个不用重启tomcat完成地址映射的方法
- 《linux内核完全剖析》笔记02-中断处理
- HDU5713 K个联通块
- JAVA自学笔记
- Docker常用命令
- SparkR Notebooks
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 字符集过滤器
- hello
- 具有回弹效果的RecyclerView,RecyclerView外层可滚动容器(二)