中断架构

如果程序总是顺序执行,那么事情将变得非常简单。但事情往往和人们所期望的不太一样,中断和异常会打断顺序执行的程序流,转而进入一条完全不同的执行路径。操作系统的内核为什么那么难懂,很大一部分要归功于它们。下面将介绍现代CPU架构中的中断和异常机制。

中断架构

从某种意义上说,现代计算机架构是由大量的中断事件驱动的。中断提供给外部硬件设备一种“打断CPU当前执行任务,并响应自身服务”的手段。

1、可编程中断控制器

中断从设备发送到CPU需要由被称为“中断控制器”的部件转发。中断控制器发展至今,经历了PIC(可编程中断控制器)和APIC(高级可编程中断控制器)两个阶段。

2、PIC

8259A芯片即常说的PIC,它具有IR0~IR7共8个中断管脚连接外部设备。中断管脚具有优先级,其中IR0优先级最高,IR7最低。PIC有如下三个重要的寄存器。

(1)IRR中断请求寄存器:共8位,对应IR0~IR7这8个中断管脚。某位置一代表收到对应管脚的中断但还未提交给CPU。

(2)ISR服务中寄存器:共8位。某位置1代表对应管脚的中断已经提交给CPU处理,但CPU还未处理完。

(3)IMR中断屏蔽寄存器:共8位。某位置一对应的中断管脚被屏蔽。

除此之外,PIC还有一个EOI位,当CPU处理完一个中断时,通过写该位告知PIC中断处理完成。PIC向CPU递交中断的流程如下:

(1)一个或多个IR管脚上产生电平信号,若对应的中断没有被屏蔽,IRR中相应的位 被置1。

(2)PIC拉高INT管脚通知CPU中断发生。

(3)CPU通过INTA管脚应答PIC,表示中断请求收到。

(4)PIC收到INTA应答后,将IRR中具有最高优先级的位清0,并设置ISR中对应的位。

(5)CPU通过INTA管脚第二次发出脉冲,PIC收到后计算最高优先级中断的vector,并将它提交到数据线上。

(6)等待CPU写EOI。收到EOI后ISR中最高优先级的位被清0,如果PIC处于AEOI模式,当第二个INTA脉冲收到后,ISR中最高优先级的位自动清0。

3、APIC

PIC可以在UP(单位处理器)平台上工作,但无法用于MP(多处理器)平台。为此APIC应运而生。APIC由位于CPU中的本地高级可编程中断控制器和位于主板南桥中I/O高级可编程中断控制器两部分构成。其中IOAPIC通常有24个不具有优先级的管脚,用于连接外部设备。当收到某个管脚的中断信号后,IOAPIC根据软件(通常是操作系统)设定的PRT表,查找到管脚对应的RTE表通过RTE的各个字段,格式化出一条包含该中断所有信息的中断消息,再由系统总线发送给特定CPU的LAPIC,LAPIC收到该消息后择机将中断递交给CPU处理。

在LAPIC内部,也有IRR、ISR和EOI寄存器,其中IRR、ISR为256位,EOI为32位,它们的功能和PIC的大体类似。APIC系统中,中断的发起大致流程如下。

(1)IOAPIC收到某个管脚产生的中断信号。

(2)查找PRT表获得该管脚对应的RTE。根据RTE各字段格式化出一条中断消息。并确定发送给哪个CPU的LAPIC。

(3)通过系统总线或APIC总线发送中断消息。

(4)LAPIC收到中断消息,判断是否由自己接收。

(5)如确定接收,将IRR中对应的位置。同时确定此时是否将该中断交由CPU处理。

(6)如果提交中断给CPU处理,从IRR获取最高优先级的中断,将ISR中对应的位置,并提交中断。对于edge触发中断,IRR中对应位此时清0.

(7)CPU处理完中断,软件写EOI寄存器告知中断处理完成,对于level触发中断,IRR中对应位此时清0.LAPIC可提交下一个中断。

处理器间中断

在MP(多处理器)平台上,多个CPU要协同工作,处理器间中断IPI 提供CPU之间相互通信的手段。cpu可以通过LAPIC的ICR(中断命令寄存器)向指定的一个/多个CPU发送中断。

操作系统通常使用IPI来完成诸如进程转移,中断平衡和TLB刷新等工作。

中断的重要概念

(1)中断的分类

中断可以从多个方面进行分类。从中断源的角度来看可以分为如下几类。

中断可以从多个方面进行分类。从中断源的角度来看,可以分为如下几类。

外部中断:指连接在IOAPIC上设备产生的中断、LAPIC上连接的设备或LAPIC内部中断源产生的中断以及处理器间中断。

可屏蔽中断:指可以通过某种方式进行屏蔽的中断。与之对应的概念是不可屏蔽中断。

软件产生的中断:指通过INT n 指令产生的中断。

这样的分类并非绝对,例如外部中断通常是可屏蔽中断,但也可能属于不可屏蔽中断。通常,根据外部中断的触发方式,又把它们分为如下几类。

(1)edge触发中断:指中断边沿方式触发。ISA设备、时钟设备多使用这种触发方式。

(2)level触发中断:指中断以电平方式触发,在中断的程序应答设备前,该电平一直有效。PCI设备使用这种触发方式。

2、中断的优先级

在使用PIC的系统中,PIC管脚决定了中断的优先级,连接IR0的设备具有最高优先级,连接IR7的设备优先级最低。在APIC系统中,IOAPIC的管脚不再具有优先级,设备的中断优先级由它所连接管脚对应RTE的vector字段决定。vector是x86架构用于索引IDT表的下标,范围从0~255,值越大优先级越高。其中,32~255可以供外部中断使用。

在现代操作系统中,有几个概念和vector常联系在一起使用,这里简单介绍一下。

IRQ:PIC时代的产物,由于ISA设备通常是连接到固定的PIC管脚,所以说一个设备的IRQ实际是指它连接的PIC管脚号。IRQ暗示着中断优先级,例如IRQ0比IRQ3有着更高的优先级。当前进到APIC时代后或许是出于习惯,人们仍然习惯用IRQ表示一个设备的中断号,但对于16以下的IRQ它们不可能再与IOAPIC的管脚对应。

GSI:ACPI引入的概念,它为系统中每个中断源指定一个唯一的中断号。IRQ和GSI在APIC系统中常常被混用,实际上对于15以上的IRQ它和GSI相等。

在这里,GSI和IRQ可以看作等同的概念,表示某个设备的中断号。它们与vector的关系由操作系统决定,通常是在设备驱动注册中断处理程序时由操作系统分配。

3、中断的屏蔽

无论是在PIC收到中断信号后还是LAPIC收到中断消息后,并不一定都是马上交给CPU处理的,这还要取决于CPU当前是否屏蔽中断。当CPU屏蔽中断时,中断会被依附在PIC/LAPIC的IRR寄存器中,一旦CPU开启中断,会在第一时间相应PIC/LAPIC所依附的中断。cpu可以通过以下几种方法屏蔽/开启中断。

(1)CLI/STI指令:这是操作系统最常用的屏蔽/开启中断的方法。CLI指令将本CPU的EFLAGS寄存器的IF位清0,阻止接收中断;STI指令将IF位置一,允许接收中断。这两条指令都只对当前CPU起作用,而不影响其他CPU。

(2)TPR寄存器:根据该寄存器值代表的优先级,部分屏蔽外部中断。

(3)PIC/IOAPIC的中断屏蔽位:PIC可以通过IMR寄存器屏蔽对应管脚。IOAPIC可通过RTE中的mask位屏蔽对应管脚。该方法不会将中断依附到IRR而是直接忽略,对于edge触发中断可能导致中断丢失。

4、IDT表

IDT表实际就是个大数组,用于存放各种“门”(中断门、陷阱门、任务门),这些门是中断和异常通往各自处理函数的入口。当一个中断或异常发生时,CPU用它们对应的vector号索引IDT表以获得对应的“门”。每个门占8B,x86最多有256个vector,故IDT表最大长度为8*256=2048B

IDT表的基地址存放在IDTR寄存器中,该寄存器和GDTR类似,由一个基地址(Base)和长度(Limit)字段构成,通过LIDT/SIDT指令可以加载和存储IDTR寄存器。IDT表要求被对齐到8B边界以提高效率。

5、中断门

“门”是入口,中断门就是中断入口。中断门实际上是一种段描述符,称为系统描述符,由段描述符的S位控制。

其中,段选择符、偏移量字段可以看成一个逻辑地址,通过索引GDT将该逻辑地址转换成中断处理函数入口的线性地址。这里要特别注意的是DPL字段,很多操作系统把门的DPL设置成0,而在之前讲过。只有当CPL<=DPL、CPL<=RPL访问才被允许。

这就引出一个问题:程序在用户态时CPL=3发生中断,岂不是不能过一个DPL=0的中断门。实际上,中断门和陷阱门的DPL只在使用INT n指令引起中断/异常时才检查,硬件产生的中断/异常不检查。P字段代表该中断门是否有效,清0无效。

虽然没有强行规定中断一定要使用中断门,但通常操作系统是这样做的。中断门和陷阱门的唯一区别是程序通过中断门跳转后,EFLAGS寄存器的IF位自动清0,中断关闭。而陷阱门没有这样的效果。

猜你喜欢

转载自blog.csdn.net/d1306937299/article/details/88127418