中断概念 与 中断过程
80x86中断、保护模式与实模式下的中断过程
说明:以下是对非任务切换的中断过程的讨论。
--2012年11月15日12:18:41 --2012年12月9日14:30:29修改
中断是操作系统实现进程的调度、设备的访问、用户态和内核态的切换,各种异常的处理等等的基础。
由于中断的机制和实现是和硬件密切相关的,这里只总结一下Intel 80x86系列CPU 的中断在硬件层面上处理过程。
1. 中断分类与区别
在微机系统中,中断可分为外部中断(或硬件中断)和内部中断(或软件中断)。 ① 外部中断
外部中断是指由外部设备通过硬件请求的方式产生的中断,也称为硬件中断。外部中断又可分为非可屏蔽中断(non-maskable interrupt,NMI )和可屏蔽中断(interrupt request),CPU 通过NMI 和INTR 引脚分别接收这两种中断。
不可屏蔽中断 NMI :当外设通过非屏蔽中断请求信号向微处理器提出中断请求时,微处理器在当前指令执行结束后,就立即无条件的予以响应,这样的中断就是不可屏蔽中断。不可屏蔽中断在外部中断源中优先级最高,主要用于处理系统的意外或故障,如电源掉电、存储器读/写错误、扩展槽中输入/输出通道错误等。
可屏蔽中断 INTR :CPU 对可屏蔽中断请求的响应是有条件的,它受中断允许标志位IF 的控制。当IF =1时,允许CPU 响应INTR 请求;当IF =0时,禁止CPU 响应INTR 请求。可屏蔽中断用于CPU 与外设进行数据交换。可屏蔽中断受8259A 可编程中断控制器的控制。时钟中断(8253定时器发出的中断信号)就属于可屏蔽中断。
② 内部中断
内部中断是由CPU 运行程序错误或执行内部程序调用引起的一种中断,也称为软件中断,它分为异常和INT n 指令中断两类,内部中断不受eflags 中IF 位的影响。
异常分为故障(Fault )、陷阱(T rap )和中止(Abort )3种。是在指令执行过程中由于微处理器内部操作发生异常引起的,如硬件失效或非法的系统调用,以及程序员预先设置断点等。
INT n 指令中断是指系统执行INT n 指令所引起的中断。其实INT n 和INT0也归类于异常,属同步性事件。
③ 中断与异常的区别
Intel 的官方文档里将中断和异常理解为两种中断当前程序执行的不同机制。这是中断和异常的共同点。不同点在于:
中断(interrupt)是异步的事件,典型的比如由I/O设备触发;
异常(exception)是同步的事件,典型的比如处理器执行某条指令时发现出错了等等。
它们的具体区别很多书籍和官方文档都解释的比较清楚这里不再赘述。
关于它们的区别有两点是需要注意的:
1)平常所说的屏蔽中断是不包括异常的,即异常不会因为CPU 的IF 位被清(关中断,指令:cli )而受影响,比如缺页异常,即使关了中断也会触发CPU 的处理。
2)通常说的int 80h这种系统调用(Linux 操作系统中的系统调用)使用的中断方式实际上硬件上是理解为异常处理的,因此也不会被屏蔽掉,这也很好理解,int 80h 这种中断方式是程序里主动触发的,对于CPU 来说属于同步事件,因此也就属于异常的范畴。
需要明确的一点是CPU 对于中断和异常的具体处理机制本质上是完全一致的。
2.Intel 80x86 CPU—32位保护模式下的中断(异常)处理过程
0)中断响应的事前准备:【注意,这是准备阶段】
系统要想处理各种不同的中断,就需要事先编写好各种中断服务程序,并使CPU 能够利用中断信号找到所对应的中断服务程序。具体如下:
[a] 系统将所有的中断信号统一进行了编号(一共256个:0~255),这个号称为中断向量,具体哪个中断向量表示哪种中断有的是规定好的,也有的是在给定范围内自行设定的。
中断向量和中断服务程序的对应关系主要是由IDT (中断描述符表)负责。操作系统在IDT 中设置好各种中断向量对应的中断描述符(一共有三类中断门描述符:任务门、中断门和陷阱门),留待CPU 查询使用。而IDT 本身的位置是由IDTR 寄存器保存的,当然这个地址也是由OS 填充的。
下面的示意图显示了IDT 的基本结构和IDTR 寄存器是如何指示IDT 的位置和长度的:
[b] 中断服务程序具体负责处理中断(异常)的代码是由软件,也就是操作系统实现的,这部分代码属于操作系统内核代码。也就是说从CPU 检测中断信号到加载中断服务程序以及从中断服务程序中恢复执行被暂停的程序,这个流程基本上是硬件确定下来的,而具体的中断向量和服务程序的对应关系设置和中断服务程序的内容是由操作系统确定的。
1)CPU 检查是否有中断/异常信号: CPU 在执行完当前程序的每一条指令后,都会去确认在执行刚才的指令过程中中断控制器(如:8259A )是否发送中断请求过来,如果有那么CPU 就会在相应的时钟脉冲到来时从总线上读取中断请求对应的中断向量。
对于异常和系统调用那样的软中断,因为中断向量是直接给出的,所以和通过IRQ (中断请求)线发送的硬件中断请求不同,不会再专门去取其对应的中断向量。
2)根据中断向量到IDT 表中取得处理这个向量的中断程序的段选择符:
CPU 根据得到的中断向量到IDT 表里找到该向量对应的中断描述符,中断描述符里保存着中断服务程序的段选择符。
3)根据取得的段选择符到GDT (全局描述符表)中找相应的段描述符:
CPU 使用IDT 查到的中断服务程序的段选择符从GDT 中取得相应的段描述符,段描述符里保存了中断服务程序的段基址和属性信息,此时CPU 就得到了中断服务程序的起始地址。
这里,CPU 会根据当前CS 寄存器里的CPL (当前进程的权限级别)和GDT 的段描述符的DPL (规定访问该段的权限级别),以确保中断服务程序是高于当前程序的,如果这次中断是编程异常(如:int 80h系统调用),那么还要检查CPL 和IDT 表中中断描述符的DPL ,以保证当前程序有权限使用中断服务程序,这可以避免用户应用程序访问特殊的陷阱门和中断门。
如下图显示了从中断向量到GDT 中相应中断服务程序起始位置的定位方式
:
4)CPU 根据特权级的判断设定即将运行的中断服务程序要使用的栈的地址:
CPU 会根据CPL 和中断服务程序段描述符的DPL 信息确认是否发生了特权级的转换,比如当前程序正运行在用户态,而中断程序是运行在内核态的,则意味着发生了特权级的转换,这时CPU 会从当前程序的TSS 信息(该信息在内存中的首地址存在TR 寄存器中)里取得该程序的内核栈地址,即包括ss 和esp 的值,并立即将系统当前使用的栈切换成新的栈。这个栈就是即将运行的中断服务程序要使用的栈。紧接着就将当前程序使用的ss,esp 压到新栈中保存起来[注意:此处也属于保护现场]。
5)保护当前程序的现场:
CPU 开始利用栈保护被暂停执行的程序的现场:依次压入当前程序使用的eflags ,cs ,eip ,errorCode (如果是有错误码的异常)信息。
官方文档给出的栈变化的示意图如下:
6)跳转到中断服务程序的第一条指令开始执行:
CPU 利用中断服务程序的段描述符将其第一条指令的地址加载到cs 和eip 寄存器中,开始执行中断服务程序,中断服务程序一开始就将用到的其他寄存器(如ds ,es ,fs ,edx ,ecx ,ebx 等)等现场进一步保存。这意味着先前的程序被暂停执行,中断服务程序正式开始工作。
7)中断服务程序处理完毕,恢复执行先前中断的程序:
在每个中断服务程序的最后,必须有中断完成返回先前程序的指令,这就是iret (或iretd )。程序执行这条返回指令时,会从栈里弹出先前保存的被暂停程序的现场信息,即eflags,cs,eip 重新开始执行。如果存在特权级转换还会弹出ss 和esp ,这样也意味着栈也被切换回原先使用的栈了。
这里有个地方需要注意:如果此次处理的是带有错误码(errorCode)的异常,CPU 在恢复先前程序的现场时,并不会弹出errorCode ,也就是说CPU 似乎忘记了曾经压过一个errorCode 入栈,因此要求相关的中断服务程序在调用iret 返回之前需要主动弹出errorCode 。
3.Intel 80x86 CPU—实模式下的中断(异常)处理过程
实模式下的中断处理比保护模式下的要简单。大概步骤如下: 1)(从中断信息中)取得中断类型码; 2)标志寄存器的值入栈; 3)设置标志寄存器的第8位TF (=0时,关闭单步中断)和第9位IF (=0时,屏蔽中-------------------------------------------------------------中断处理---------------------------------------------------------------- 断)的值为0;
4)CS 内容入栈
5)IP 内容入栈 6)从内存地址为 中断类型码*4 和 中断类型码*4+2 的两个字单元中读取中断服务程序的入口地址,设置IP 和CS 。
---------------------------------------中断处理完成,开始执行中断服务程序-------------------------------------------------
中断服务程序执行............ (中断服务程序一开始就对用到的其他寄存器等进行压栈保存)
-----------------------------------------中断服务程序执行完成,中断返回------------------------------------------------------
从栈中弹出寄存器的值,送入相应寄存器,从而恢复现场。 --------------------------------------------------------------中断完成------------------------------------------------------------------
[注]:
1. 如有问题,欢迎联系:
2. 本文参考了以下文献或网址:
http://blog.sina.com.cn/s/blog_5ffeae360100f t wt.html