目录

中断

中断分类

中断按照是否由CPU内部发生分为

  • 外部中断 (由CPU外部引发,比如外设、网卡等)
  • 内部中断 (由CPU内部引发,比如系统调用)

外部中断分为

  • 可屏蔽中断 (比如网卡发出数据读取中断,可以屏蔽)
  • 不可屏蔽中断 (比如掉电、设备损坏等)

内部中断分为

  • 软中断 (由软件程序触发,比如系统调用0x80号中断)
  • 异常 (异常也是一种特殊的中断,比如除0异常、缺页异常)

https://raw.githubusercontent.com/biningo/cdn/master/img1/interrupt.png

中断产生和调用过程

触发中断其实就是给出一个 中断号 ,然后CPU根据中断号去查找中断对应的程序进行执行的一个过程

操作系统会设置一个 IDT中断描述符表 ,里面记载了各个中断号对应的程序的入口地址,操作系统内核在运行初始化的时候必须初始化 中断寄存器指向的位置 ,因为一旦发生中断CPU就会去中断寄存器指向的IDT中去寻找中断程序

发生中断时用户态就会转化为内核态,CPU会保存程序当前执行的状态,比如会将栈指针、各个寄存器值、PC指针压入内核栈,然后开始执行中断处理程序,执行完毕之后再恢复现场,也就是将栈中的值都出栈然后放到各个寄存器中继续执行之前的代码

这里需要注意中断的进程状态管理和进程调度的进程状态管理这两个是不一样的

中断发生时的进程状态是保存在内核栈中,而进程调度发生时需要将进程的状态保存在PCB中

那么这个中断是如何引发的呢?

软中断和异常容易理解,CPU有一个int指令,后面跟给一个中断号,程序只需要执行这个指令即可触发软中断或异常,最常见的软中断就是int 0x80中断,此中断是系统调用中断,所有的系统调用都会触发这个中断,系统调用中断还需要给出 系统调用号 ,系统调用中断处理程序会根据系统调用号去执行相应的系统调用代码

外中断需要经过一个叫 中断代理 的硬件,该硬件连接了所有外设接口的中断线,外设如果需要引发中断则只需要往这个中断线里面传输信号到中断代理即可,中断代理会根据不同的信号转化为相应的 中断号 ,中断代理和CPU只连接了两条线: INTR和NMI INTR表示可屏蔽中断,比如网卡发出的中断、NMI表示不可屏蔽中断

可屏蔽中断的话只需要CPU设置状态寄存器中相应的位就表示屏蔽这些中断,注意: 软中断、异常都是会忽略该位的 也就是说软中断和异常都是不可屏蔽的,软中断通常来说是系统调用,用户进程需要系统调用则操作系统必须响应,否则会造成用户程序卡死无法获得操作系统提供的帮助,会造成用户体验不好,异常更不用说了,需要立即处理

中断代理将相应的中断号输出到INTR线中通知CPU,CPU没执行一条指令都会检查该线是否有中断信号(注意:CPU检查中断是由硬件电路来实现的,并不会有任何的损耗)

如果有中断信号则CPU会立即检测到

中断的上半部分和下半部分

一个中断程序可以分为 上部分和下部分 ,中断处理时可以先执行上半部分,这个部分一般来说比较紧急,等CPU空闲之后再继续执行下半部分

比如网卡发出数据读取操作,此时CPU先执行上半部分的中断程序:先将网卡缓存区里的数据拷贝到内核数据区,这个网卡就不会因为缓存区满而频繁丢包了(相当于一个紧急救火),然后等CPU空闲了之后再执行中断下半部分,也就是将内核数据区域的数据拷贝到用户空间供用户使用

操作系统时钟中断

这个时钟和CPU的时钟不是一个概念,但是他们的功能都是差不多的,都是为了使操作系统或则CPU能正确的工作,时钟就相当于一个 节拍器,很多硬件设备也有时钟,为的就是让各个电路有序的进行操作

操作系统的时钟中断由 可编程的脉冲器 产生的,因为操作系统需要和硬件配合的,所以一般和硬件结合的比较紧密,该硬件脉冲频率是和操作系统厂商商量好的,并且可以人为的编程去改变脉冲的频率

时钟中断会定时的引发然后传递到CPU的NMI引脚,时钟中断属于不可屏蔽中断

时钟中断的作用非常大,可以说没有时钟中断操作系统就没有控制权,时钟中断的作用如下:

  • 更新系统的时间
  • 定时的将控制权转移到操作系统的程序中,以便操作系统进行各个调度工作比如进程时间片调度,每经过一个时钟则时间片减一 (如果没有时钟中断,那么如果用户程序如果一直不进行系统调用、不引发异常那么操作系统可能永远也拿不到CPU的控制权)

参考

《操作系统真象还原》