《深入理解Linux内核》读书笔记-第四章-中断和异常(1)

来源:岁月联盟 编辑:exp 时间:2012-02-19
中断(interrupt)通常被定义为一个事件,该事件改变处理器执行的指令顺序。这样的事件与CPU芯片内外部硬件电路产生的电信号相对应。
 
中断通常分为同步(synchronous)中断和异步(asynchronous)中断:
同步中断是当指令执行时由CPU控制单元产生的,之所以称为同步,是因为只有在一条指令终止执行后CPU才会发出中断。
异步中断是由其他硬件设备依照CPU时钟信号随机产生的。
在Intel微处理器手册中,把同步和异步中断分别称为异常(exception)和中断(interrupt)。
 
中断是由间隔定时器和I/O设备产生的,而异常是由程序的错误产生的,或者是由内核必须处理的异常条件产生的。
 
 
中断信号的作用:
中断信号提供了一种特殊的方式,使处理器转而去执行正常控制流之外的代码。当一个中断信号达到时,CPU必须停止它当前正在做的事情,并且切换到一个新的活动。为了做到这一点,就要在内核态堆栈保存程序计数器的当前值,并把与中断类型相关的一个地址放进程序计数器。
 
中断处理与进程切换有一个明显的差异:由中断或异常处理程序所执行的代码不是一个进程,更确切的说,它是一个内核控制路径,代表中断发生时正在运行的进程执行。作为一个内核控制路径,中断处理程序比一个进程要轻,中断的上下文很少,建立蒙昧无知中止中断处理所需要的时间很少。
 
中断处理是由内核执行的最敏感的任务之一,因为它必须满足以下约束:
当内核正打算去完成一些别的事情时,中断随时会到来。因此,内核的目标就是让中断尽可能快的处理完,尽其所能把更多的处理向后推迟。内核响应中断后需要进行的操作分为两部分:关键而紧急的部分,内核立即执行; 其余推迟的部分,内核随后执行。
因为中断随时会到来,所以内核可能正在处理其中一个中断时,另一个中断又发生了。因此,中断处理程序必须编写成使相应的内核控制路径能以嵌套的方式执行。当最后一个内核控制路径终止时,内核必须能恢复被中断进程的执行,或者,如果中断信号已导致了重新调度,内核能切换到另外的进程。
尽管内核在处理前一个中断时可以接受一个新的中断,但在内核代码中还是存在一些临界区,在临界区中,中断必须被禁止。必须尽可能地限制这样的临界区,因为,根据以前的要求,内核,尤其是中断处理程序,应该在大部分时间内以开中断的方式运行。
 
中断和异常:
Intel文档把中断和异常分为以下几类:
中断:
可屏蔽中断(maskable interrupt):一个屏蔽的中断只要还是屏蔽的,控制单元就忽略它。
非屏蔽中断(nonmaskable interrupt):非屏蔽中断总是由CPU辨认。
异常:
处理器探测异常(processor-detected exception):当CPU执行指令时探测到一个反常条件所产生的异常,可分为三组:
故障(fault):通常可以纠正,一旦纠正,程序就可以不失连贯的情况下重新开始。
陷阱(trap):主要用于调试程序。在陷阱指令执行后立即报告,内核把控制权返回给程序后就可以继续它的执行而不失连贯性。
异常中止(abort):发生一个严重错误,控制单元出了问题,不能在eip寄存器中保存引起异常的指令所在的确切位置。异常中止用于报告严重的错误,如硬件故障等。由控制单元发送的这个中断信号是紧急信号,用来把控制权切换到相应的异常中止处理程序,这个异常中止处理程序除了强制受影响的进程终止外,没有别的选择。
编程异常(programmed exception): 在编程者发出请求时发生。控制单元把编程异常作为陷阱来处理,编程异常通常也叫做软中断(software interrrupt)。这样的异常有两个用途:执行系统调用及给调试程序通报一个特定的事件。
每个中断和异常是由0~255之间的一个数来标识。Intel把这个8位无符号整数叫做一个向量(vector)。非屏蔽中断的向量和异常的向量是固定的,而可屏蔽中断的向量可以通过对中断控制器编程来改变。

作者 疯狂伯德