我们这里讨论在中断信号已经被中断系统的硬件中断装置接收和响应之后,对应的软件中断处理程序进行中断处理的具体过程。
在处理器的控制权转移到中断处理程序之后,中断处理程序开始工作,其中包括检查I/O相关的状态信息,操纵I/0设备或者在设备和内存之间传送数据等。具体的中断处理程序的内容,完全是依据中断请求的类别和要求的不同,而分别设计的。
在中断处理程序结束工作之后,处理器会检测到一条中断返回指令。在执行中断返回指令时,处理器会把原先被中断的程序的上下文环境从系统堆栈中恢复。处理器状态也从管态恢复成被中断时的目态。整个中断处理结束。
处理器开始一个新的指令周期,继续执行原来被中断的程序。
上述整个中断信号的接收、响应和处理过程,可以简要地归纳为:接收和响应中断,保护中断断点现场,分析中断向量,调用中断处理程序,中断处理结束恢复现场,原有程序继续执行。
几种典型中断的处理
这里介绍几种计算机系统中比较典型的中断处理,包括L0中断、时钟中断、硬件故障中断、程序性中断和系统服务请求(自愿性中断)等。
I/O中断
I/O中断一般由O设备的控制器或者通道发出。I/O中断通常可分成两大类:I/O操作正常结束以及I/O异常。对于前者来说,如果要继续进行I/O操作,则需要在准备好以后重新启动I/O。若请求I/O的程序正处于等待I/O的状态,则应该将其唤醒。对于后者,常常需要重新执行失败的I/O操作,不过这个重试的次数常常有一个上限,因为错误可能由硬件损伤引起,当重试次数过大的时候,系统将判定硬件故障,并通知管理员。
比如,我们平常在PC上用 CD-ROM观看VCD或DVD的碟片时,有时会碰到读碟出错。在重复读碟几次之后,如果读碟岀错继续,系统就会停止读碟,并报告出错,甚至退出碟片。
时钟中断
时钟中断是计算机系统多道能力的重要条件之一。时钟中断处理程序通常要做较多的与系统运转、管理和维护相关的工作,它们对于整个系统是非常重要的,主要内容如下。
①维护软件时钟。系统有若干个软件时钟,控制着定时任务以及进程的处理器时间配额,时钟中断需要维护,定时更新这些软件时钟。
②处理器调度。维护当前进程的时间片软件时钟,并在时间片到时后运行调度程序选择下一个被调度的进程。
③控制系统定时任务。通过软件时钟和调度程序定时激活一些系统任务,例如监测死锁、进行系统记账、对系统状况进行审计等。
④实时处理,例如产生系统“心跳”,激活系统看门狗等。
当然,在不同的操作系统设计中,时钟中断处理的内容也不一样。很多系统的时钟中断通常只处理软件时钟,并在一定条件下激活系统调度程序。
一般来说,调度程序并不在时钟中断里,因为时钟中断的优先级往往比较高,而且频繁发生,如果时钟中断处理时间过长,就会使一些较低优先级的中断丢失。
硬件故障中断
硬件故障一般是由硬件的问题引起的,排除此类故障通常需要人工的于预,例如复位硬件或者更换设备等。
硬件故障中断处理程序需要做的工作是保存现场,使用一定的手段警告管理员并提供一些辅助的诊断信息。此外在高可靠的系统中,中断处理程序还需要评估系统的可用性,并尽可能地恢复系统。
例如,使用 Windows9X的系统在关键硬件发生故障时,会出现系统蓝屏死机。这时操作系统实际上进入了相应的故障处理程序,并发现这个故障是不可恢复的,于是在屏幕上打印出了发生故障时的程序位置(通常在某个管态驱动程序中),并且开始进行内存转储(将定范围的内存内容写到磁盘上去,实际上是系统发生故障时的全系统“快照”),以备日后进行程序调试级故障诊断。
程序性中断
程序性中断多数是程序指令出错、指令越权或者指令寻址越界而引发的系统保护。它的处理方法可以依据中断是否可以被用户程序自行处理,而分成两类。
第一类为程序性中断,只能由操作系统完成。这种情况多为程序试图做自己不能做的操作引起的系统保护,例如访问合法的但是不在内存的虚地址引发的缺页中断等。这时候的处理一般由操作系统的相关扩展功能模块完成。
第二类为程序性中断,可以由程序自己完成。例如一些算术错误。因为不同的程序可能有不同的处理方法,所以很多操作系统提供由用户自行处理这类中断的“绿色通道”。一般来说,系统调试中断,如断点中断、单步跟踪等,用以支持各种程序的调试,是可以被用户程序处理的。
系统服务请求(自愿性中断)
系统服务请求一般由处理器提供的专用指令(又称访管指令)来激发。例如x86处理器提供int指令,用来激发软件中断,其他的不少处理器则专门提供系统调用指令 syscall。执行这些指令的结果是系统被切换到管态,并且转移到一段专门的操作系统程序处开始执行。这种指令的格式通常是指令名加上请求的服务识别号(有时是中断号)。操作系统利用处理器提供的这种接口建立自己的系统服务体系。处理器一般不负责定义系统调用所传递的参数格式。因为不同的系统会提供不同的系统调用,而不同的系统调用需要不同的参数,所以给系统服务例程传递什么样的参数,以及如何传递这些参数都由操作系统规定。
这方面的实例可以看一下 MS-DOS定义的2h号中断的系统服务功能以及参数列表,这可以在有关 MS-DOS程序设计的书的附录中查到。
现代操作系统一般不会提供直接使用系统调用指令的接口,通常的做法是提供一套方便、实用的应用程序函数库(又称为应用程序设计接口API)。这些函数从应用的较高层面重新封装了系统调用,一方面屏蔽了复杂的系统调用传参问题(用汇编语言传参),另一方面是高级语言接口,有助于快速开发。还有的系统在更高层面提供了系统程序设计的模板库和类库。