这里以linux-kernel 0.11版本为基础整理中断相关知识,目的在于对于中断有一个全面、清晰和简洁的认识
1、Linux的中断类型
Linux的各种中断都是由系统负责统一处理的。在响应一个特定的中断的时候,内核会执行一个函数,该函数叫做中断处理函数或中断服务例程。CPU执行完一条指令后,下一条指令的逻辑地址会被放在相应的寄存器中(CS和EIP),在执行新指令之前,系统会检查是否有中断产生(有相应的寄存器来表示状态),如果有,就对中断进行处理。Linux处理中断,大致可分为如下的几步:
(1)、保存正在执行的进程的上下文,便于中断处理返回后能恢复进程的执行
(2)、对中断进行解析,确定产生中断的中断源,识别中断的类型。但系统接受中断时,能够从物理硬件中获得一个关于中断的数
,用这个数去做查表操作,能获得关于这个中断类型、中断处理程序等相关信息
(3)、内核调用由第二步获得的中断处理程序,对中断进行处理
(4)、中断处理程序执行完对中断的处理后返回。恢复之前被中断的进程的上下文,或者根据需要调度优先级更高的进程去执行
中断信号可分为两类:硬件中断和软件中断,软件中断一般被称为异常。Intel x86公有256个中断,每个中断都有一个0~255之间的数来表示,Intel将前32个中断号(0~31)已经固定设定好或者保留未用。中断号32~255分配给操作系统和应用程序使用。在Linux中,中断号32~47对应于一个硬件芯片的16个中断请求信号,这16个中断包括时钟、键盘、软盘、数学协处理器、硬盘等硬件的中断。系统调用设为中断号128,即0x80。
2、中断描述表
获取中断号(或称为中断向量)的过程涉及到太多的硬件过程,这里不做介绍。系统获得中断向量之后,要获得相应的处理程序,需要去做一个查表的操作,这里所查询的这个表,就是中断描述表。
中断描述表是存储系统中断向量对应中断处理程序的表。Intel x86中共有256个中断,因此中断描述表中也有256项,每一项对应一个中断。系统以中断向量作为索引从表中取出相应的中断服务例程。
[中断描述表在内存中断的位置]
中断描述表可以在内存中的任意位置,它的具体地址保存在IDTR寄存器中。
[中断描述表的初始化]
在Linux内核版本0.11中,中断描述表的初始化分为两个部分。第一部分是在内核引导启动部分,在head.s中实现。这里的效果是将中断描述符表(用IDT表示),设置成具有256项,并且都指向ignore_int的中断门。然后将IDT的地址加载到IDTR寄存器中。因此,这里的初始化只是把所有中断的服务例程都设置成了一个哑的中断服务程序,即不做任何中断的处理。第一部分的初始化代码(AT&T的汇编语言格式)很短,这里摘抄如下。setup_idt子程序在head.s的第24行被调用