os 004 中断
os 004 中断
中断分类
外部中断
外部中断是来自CPU外部的中断,外部中断源又必须是硬件,所以外部中断又称为硬件中断。
可屏蔽中断
通过intr引脚进入CPU,可屏蔽中断可以通过EFLAGS的IF位屏蔽掉。不可屏蔽中断
通过NMI引脚进入CPU,不可屏蔽中断不可以通过EFLAGS的IF位屏蔽掉。
内部中断
内部中断可分为软中断和异常。
软中断
由软件主动发起的中断。不受IF位影响。异常
异常分为以下三种:- FAULT 故障,比如缺页异常。
- TRAP 陷阱
- 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的一些信号的寄存器
INT:8259A选出优先级最高的中断请求之后,发送信号给CPU。
INTA:INT acknowledge, 中断响应信号。接收来自CPU的INTA接口的中断响应信号。
IMR:中断屏蔽寄存器,8位,屏蔽某个外设的中断。
IRR:中断请求寄存器,8位,接受IMR过滤后的中断信号并锁存,相当于维护未处理的中断信号请求队列。
PR: 优先级仲裁器。多个中断同时发生的时候找出优先级更高的中断。
ISR: 中断服务寄存器,8位,保存正在被处理的中断服务。
一个8259A由8个IRQ接口,使用8位寄存器中的每一位代表一个IRQ接口。
8259A的中断处理流程
当某个外设发出一个中断信号后,由于主板已经把信号通路指向了8259A芯片的某个IRQ接口,所以该中断信号会被送入8259A。8259A先检查IMR寄存器是否屏蔽了来自该IRQ接口的中断信号,该为为1表示被屏蔽了。
将中断信号送入IRR寄存器,将该IRQ接口所在的IRR寄存器对应的位置1.
PR从IRR寄存器中挑选一个优先级最大的一个中断(IRQ接口号最低的)。
通过INT接口向CPU发送INTR信号。
CPU完成一条指令后,通过自己的INTA接口向8259A的INTA接口发送中断响应信号。
8259A收到CPU的中断响应信号后,将刚刚挑选出的优先级最大的中断在ISR寄存器中对应的位置1,表示正在处理当前中断,同时在IRR中该中断位置0。
CPU再次发送INTA信号,要求获取中断向量号。如果EIO被设置为自动的话,则8259A自动将ISR对应位置0,表示中断结束,否则需要手动发送EOI信号
8259A向CPU发送中断向量号。此时如果来了一个优先级更高的中断,则将该中断替换上去,将被替换下来的中断重新装入IRR中
CPU从数据总线上拿到中断向量号止之后,用作中断向量表或者中断描述符表的索引,转到对应的中断处理程序执行。
以上为中断处理流程的上半场