os 004 中断

中断分类

外部中断

外部中断是来自CPU外部的中断,外部中断源又必须是硬件,所以外部中断又称为硬件中断。

  1. 可屏蔽中断
    通过intr引脚进入CPU,可屏蔽中断可以通过EFLAGS的IF位屏蔽掉。

  2. 不可屏蔽中断
    通过NMI引脚进入CPU,不可屏蔽中断不可以通过EFLAGS的IF位屏蔽掉。

内部中断

内部中断可分为软中断和异常。

  1. 软中断
    由软件主动发起的中断。不受IF位影响。

  2. 异常
    异常分为以下三种:

    1. FAULT 故障,比如缺页异常。
    2. TRAP 陷阱
    3. ABORT 终止

IF位只能屏蔽外部设备的中断。

指令 IF 作用
cli IF=0 关中断
sti IF=1 开中断

中断描述符表 IDT

中断描述符表是保护模式下用于存储中断处理程序入口的表,当CPU接受一个中断时,使用中断向量在这个表中检索相应的中断描述符,继而找到中断处理程序的入口地址,执行中断处理程序。

中断描述符表中可以存储中断描述符、任务们描述符、陷阱们描述符。所以中断描述符又称为

门都属于系统段,所以其描述符中的S字段全为0.

四种门描述符中type字段(D=0代表16位,D=32代表32位)

任务门 终端门 陷阱门 调用门
0101 D110 D111 D100

当代操作系统很少使用任务门和调用门

任务门

任务门和任务状态段(TSS)时Intel处理器在硬件一级上提供的任务切换机制。当代大多数操作系统都没有使用TSS实现任务的切换。

中断门

中断门描述符

作用
高32位
31-16 中断处理程序在目标段内的偏移量的31-16位
15 P
14-13 DPL
12 S=0
11-8 TYPE=D110
7-5 0
4-0 未使用
低32位
31-16 中断处理程序目标代码段描述符选择子
15-0 中断处理程序在目标段内的偏移量的15-0位

通过中断门进入中断,IF位自动置零,关中断,避免中断嵌套。中断门只存在于IDT中。

陷阱门

陷阱门描述符

作用
高32位
31-16 中断处理程序在目标段内的偏移量的31-16位
15 P
14-13 DPL
12 S=0
11-8 TYPE=D111
7-5 0
4-0 未使用
低32位
31-16 中断处理程序目标代码段描述符选择子
15-0 中断处理程序在目标段内的偏移量的15-0位

陷阱门与中断门不同的是IF位不会自动置0.

调用门

调用门给用户进程提供进入特权即0的方式,其DPL为3。他不能用于int指令调用,只能用call和jmp指令。调用门可以安装在GDT和LDT中。

中断描述符表寄存器 IDTR
47-16 15-0
32位的表基址 16位的表界限

GDT第零个描述符是不可用的,但是IDT的第零个描述符是可用的。

lidt[48位内存地址]

中断处理过程

中断的特权级检查

对于软件主动引发的中断,从特权级上来讲,必须符合下面的条件:
门描述符DPL<=CPL<目标代码段的DPL

对于外部设备引发的中断,只需要满足:
CPL<目标代码段的DPL

处理器根据中断向量号找到对应的中断描述符后,若CPL比目标代码段DPL低,则需要向高特权转移,需要切换到高特权级的栈。

中断发生,特权级发生变化时的新栈中的内容

31-16 15-0
0 ss_old
esp_old esp_old
eflags eflags
0 cs_old
eip_old eip_old
error_code error_code

执行完中断程序之后,使用iret进行返回。依次弹出EIP,CS,EFLAGS。所以中断返回前栈顶指针必须指向EIP_old。处理器根据弹出的CS指向的代码段描述符判断出该次中断是否进行了特权级改变,如果进行了特权级改变的话,继续将esp和ss弹出。

如果返回时改变了特权级则将会检查数据段寄存器DS,ES,FS,GS的内容,如果DPL比返回后的CPL高,则处理器会故意将该数据段寄存器的内容改为0,即指向第零个段描述符,从而使得处理器抛出异常。

中断错误码
31-16 15-3 2 1 0
保留0 选择子高13位索引 TI IDT EXT

TI=0,表示来自GDT,TI=1表示来自LDT。

IDT=1,表示选择子指向IDT。否则表示指向GDT或者LDT。

EXT=1,表示中断源时不可屏蔽中断或者外部设备,否则为0.

8259A

8259A的一些信号的寄存器
  1. INT:8259A选出优先级最高的中断请求之后,发送信号给CPU。

  2. INTA:INT acknowledge, 中断响应信号。接收来自CPU的INTA接口的中断响应信号。

  3. IMR:中断屏蔽寄存器,8位,屏蔽某个外设的中断。

  4. IRR:中断请求寄存器,8位,接受IMR过滤后的中断信号并锁存,相当于维护未处理的中断信号请求队列。

  5. PR: 优先级仲裁器。多个中断同时发生的时候找出优先级更高的中断。

  6. ISR: 中断服务寄存器,8位,保存正在被处理的中断服务。

一个8259A由8个IRQ接口,使用8位寄存器中的每一位代表一个IRQ接口。

8259A的中断处理流程
  1. 当某个外设发出一个中断信号后,由于主板已经把信号通路指向了8259A芯片的某个IRQ接口,所以该中断信号会被送入8259A。8259A先检查IMR寄存器是否屏蔽了来自该IRQ接口的中断信号,该为为1表示被屏蔽了。

  2. 将中断信号送入IRR寄存器,将该IRQ接口所在的IRR寄存器对应的位置1.

  3. PR从IRR寄存器中挑选一个优先级最大的一个中断(IRQ接口号最低的)。

  4. 通过INT接口向CPU发送INTR信号。

  5. CPU完成一条指令后,通过自己的INTA接口向8259A的INTA接口发送中断响应信号。

  6. 8259A收到CPU的中断响应信号后,将刚刚挑选出的优先级最大的中断在ISR寄存器中对应的位置1,表示正在处理当前中断,同时在IRR中该中断位置0。

  7. CPU再次发送INTA信号,要求获取中断向量号。如果EIO被设置为自动的话,则8259A自动将ISR对应位置0,表示中断结束,否则需要手动发送EOI信号

  8. 8259A向CPU发送中断向量号。此时如果来了一个优先级更高的中断,则将该中断替换上去,将被替换下来的中断重新装入IRR中

  9. CPU从数据总线上拿到中断向量号止之后,用作中断向量表或者中断描述符表的索引,转到对应的中断处理程序执行。

以上为中断处理流程的上半场

8259A的编程