操作系统中断概念梳理

中断

CPU 通过指令计数器(PC)存储当前要执行的指令的内存地址,并通过译码器、寄存器等硬件实现指令的执行,这是一个串行的过程。

中断的设计允许 CPU 在一个指令周期结束后,可以转去执行其他的程序(中断服务程序),在执行完后再返回原来被中断的程序。

中断的支持让 CPU 可以灵活的执行指令,从而能进一步的实现多道程序的运行(并发)、故障处理等功能。

如果没有中断,不谈故障处理、多道程序等逻辑的实现,仅检查一个设备是否完成指令这一功能,就只能通过忙等待(Busy waiting),轮询设备来得到设备返回的结果,从而造成大量的 CPU 时间被浪费。

中断的类型

根据中断的来源(中断源),可以分:

  • 外部中断源(硬中断):由外部硬件产生的信号,如键盘、打印机的中断信号
    • 软中断(softirq):对于一些处理时间较长的硬件中断,为了保证 CPU 关中断的时间很短,所以将中断分为上半部分和下半部分,下半部分也被称为软中断
  • 内部中断源(软件中断):由程序错误等产生的中断,如溢出、除 0 等。

根据中断的产生时期,可以分为同步(synchronous)中断和异步(asynchronous)中断:

  • 同步中断是当指令执行时由 CPU 控制单元产生,比如系统调用,发生时,CPU 在执行下一条指令前一定会进入中断服务程序。
  • 异步中断是指由其他硬件设备产生的中断,产生的时刻不确定,且与 CPU 的执行无关,也称外部中断。

根据中断源,可以将中断分为中断(Interrupt,来自 IO 设备)和异常(Exception,来自程序或 CPU 指令)。其中,异常可以进一步分为陷阱(trap,有意的异常,如系统调用)、故障(fault,潜在可恢复的错误)、终止(abort,不可恢复的错误)三种。

根据中断是否可以被屏蔽,分为可屏蔽中断和不可屏蔽中断。异常都是不可屏蔽中断,而硬中断中有一部分是可屏蔽中断。

根据 Intel 官方资料,同步中断称为异常(exception),异步中断被称为中断(interrupt)。
https://zhuanlan.zhihu.com/p/436901855

中断需要的硬件支持

中断的实现需要相应的硬件支持,这包括:

  • 可编程中断控制器(Programmable Interrupt Controller,PIC,常见的有 8259A/APIC):用于管理中断请求。其他 IO 设备向该控制器发出中断请求,再由中断控制器向 CPU 发送 INT(中断请求信号)。在这过程中包含了中断判优、中断嵌套、中断屏蔽相关的逻辑。
  • 状态寄存器 IF(Interrupt Flag) 位:用于控制 CPU 是否可以响应外部的可屏蔽中断请求,为 1 为可以响应。使用 sti 指令可将 IF 位置 1;使用 cli 指令置 0。IF 在一些地方也叫允许中断触发器(EINT)?。
  • INTR 引脚:位于 CPU ,接受来自中断控制器发送的 INT 中断请求信号。
  • INTA 引脚:Interrupt Acknowledgement,中断响应信号,位于中断控制器,用于 CPU 在指令周期结束后回应中断控制器。
  • NMI 引脚:用于不可屏蔽中断,无论状态寄存器中 IF 位的状态如何,CPU 收到有效的 NMI 必须进行响应。NMI 是上升沿有效; 中断类型号固定为 2; 它在被响应时无中断响应周期.不可屏蔽中断通常用于故障处理(如:协处理器运算出错,存储器校验出错,I/O 通道校验出错等).
  • 中断向量表寄存器:用于存储中断向量的入口地址(用于保护模式中)

中断可以被看成是操作系统级别的一种“回调函数”,不要因为中断本身可能带有的负面含义认为中断是某种不好的事件。

中断服务程序的流程

  • 保护现场,包括
    • 保存程序的断点:通过中断隐指令完成,即由机器自行完成
    • 保存通用寄存器和状态寄存器的内容:通过中断服务程序完成,即在中断服务程序的起始部份安排若干条存数指令,将寄存器的内容存到存储器中或堆栈中。
  • 中断服务:因不同的中断请求源而异
  • 恢复现场:中断服务程序的结尾部份,将原程序中断时的现场恢复到原来的寄存器中。
  • 中断返回:返回到中断前原程序的断点处,以便在下一个指令周期继续执行原程序

中断服务程序的入口地址(中断向量表)

中断服务程序的执行首先需要该程序的入口地址,叫做中断向量,也称为中断指针。

Intel x86 系列微机共支持 256 种向量中断,所有的中断类型都可以由一个 8 位(一个字节)的无符号整数表示,每个中断向量的长度是四个字节。在全部 256 个中断中,前 32 个(0—31)为硬件系统所预留。后 224 个可由用户设定。

需要有一个内存空间来存储所有的中断向量,这样的内存空间叫做中断向量表,也称为中断描述符表 IDT(Interrupt Descriptor Table)。

在实地址模式中,CPU 把内存中从 0 开始的 1K 字节作为中断向量表的地址空间,存储这 256 个中断向量(4B*256 = 1K)。

在保护模式中,中断向量表的基地址和大小通过中断向量表寄存器 IDTR 存储。IDTR 是 48 位的寄存器,其低 16 位保存中断描述符表的大小,高 32 位保存 IDT 的基址。

中断应用*

中断可以出现任何对及时处理某个事件或现象的需求中。

  • 时钟:用于定时发出一个用于上下文切换的中断
  • 人为设置的中断
  • 程序性事故(如浮点溢出、操作码不能识别等)
  • 硬件故障(电源掉电、接触不良等)
  • IO 设备(用于通知设备状态的变化,如准备就绪)
  • 外部事件(如键盘的 CTRL+C)

中断周期

中断周期中 CPU 需要完成的操作包括:

中断隐指令的执行:

  • 保护程序断点:将当前 PC 内容存到存储器特定单元(如 0 地址)或堆栈中。
  • 寻找中断服务程序的入口地址(通过硬件向量法或中断识别程序等方法获得),从而转去执行该设备的中断服务程序
  • 关中断:禁止 CPU 再次响应新的中断请求

中断隐指令:在机器指令系统中没有的指令,是 CPU 在中短周期内由硬件自动完成的一条指令。

?中断周期是否只是中断服务程序执行前的一个前处理过程?中断服务程序是否还会消耗若干个指令周期才结束?

中断服务程序的最后一条指令是中断返回指令,即中断返回至原程序的断点处。

中断响应的时间

CPU 在执行周期结束时刻统一向所有中断源发送中断查询信号。在指令执行周期结束后,如果有中断,则 CPU 进入中断周期,否则进入下一条指令的取值周期。

在一些情况下,指令执行时间较长,此时可以在执行过程中设置若干个查询断点,在断点时刻发送中断查询信号并响应。

硬中断->软中断的逻辑

  • ?

系统调用的逻辑

open/write/read 都是系统调用函数,这些函数的调用大多发生的用户态,但是实际执行是在内核态。系统调用的完整过程为用户态调用->内核态执行->用户态获得结果,这样一个用户态/内核态切换的过程也叫做陷阱(trap)。

Linux 中,以 open 为例,系统调用一般的过程为:

  • 用户态的程序调用 open 函数
  • 系统调用代号存入 eax 寄存器,调用 syscall 指令进入内核态
  • 根据系统调用号在 sys_call_table 表中查找 open 对应的内核函数 sys_open
  • sys_open 调用 SyS_open(其实只是 alias 而已)
  • SyS_open 调用 SYSC_open
  • SYSC_open 为实际函数实现,执行实际操作
  • 返回值存放到 rax 寄存器,调用 retq 指令返回用户态

一些特殊的中断类型

  • 处理器间中断(interprocessor interrupt)。一种特殊的硬件中断。由处理器发出,被其它处理器接收。仅见于多处理器系统,以便于处理器间通信或同步。
  • 伪中断(spurious interrupt)。一类不希望被产生的硬件中断。发生的原因有很多种,如中断线路上电气信号异常,或是中断请求设备本身有问题。

Reference

  • 《Linux 内核之旅》http://kerneltravel.net/book/
  • 《操作系统概念第七版》
  • https://web.xidian.edu.cn/mhdong/files/5fc6160c5f7c8.pdf
  • https://blog.csdn.net/farmwang/article/details/52337690
  • https://www.cnblogs.com/Courage129/p/14310441.html
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值