Interrupt(中断)
1. 概念
所谓中断,是指CPU在正常执行程序的过程中,由于某个外部或内部事件的作用,强迫CPU停止当前正在执行的程序,转去为该事件服务(称为中断服务),待服务结束后,又能自动返回到被中断的程序中继续执行。
2. 背景
中断是计算机发展中一个重要的技术,它的出现很大程度上解放了CPU,提高了CPU的执行效率。在中断出现之前,CPU对IO采用的是轮询的方式进行服务,这使得CPU纠结在某一个IO上,一直在等待它的响应,如果它不响应,CPU就在原地一直的等下去。这样就导致了其他IO口也在等待CPU的服务,如果某个IO出现了important or emergency affairs,CPU也抽不出身去响应这个IO。 为了解决这个纠结的问题就------>出现了中断。
中断控制的主要优点是只有在IO接口需要服务时才去响应它,使得CPU很淡定的做它自己的事情,只有IO口有需求的时候才去响应它。同时中断中也设计了中断优先级,来处理一些很紧急的事件
3. 分类
按照CPU与中断源(把能够提出中断请求的设备和事件称为中断源)的位置关系可分为内部中断和外部中断。
1) 内部中断:也称为异常中断,属于非屏蔽中断,是处理器检测到异常情况或执行软件中断指令引起的一种中断。通常有:除法出错中断(INT0)、断点中断(INT3)、溢出中断(INT4)和单步执行中断(INT1)等。异常又分为故障和陷阱。
2) 外部中断:也称为硬件中断,是由CPU外部引脚触发的一种中断,分为不可屏蔽中断NMI(INT2)和可屏蔽中断INTR。
4. 中断源的优先权级别
内部中断最高(除单步执行中断),其次为NMI中断,再次为INTR中断。单步执行中断最低。
5. 中断向量表
在实地址模式中,CPU把内存中从0开始到1KB的空间作为一个中断向量表。
中断向量表是中断类型号和中断服务程序入口地址之间的链接表。
系统将中断源分成256种类型,类型号由0~255(0~FFH)表示。每个中断类型分配4个连续的字节单元,用于存放该中断服务程序的入口地址,两个高字节单元存放入口的段基址,两个低字节单元存放入口的偏移地址。所以256个中断向量占用系统最低的1KB的内存。
中断类型号n与其对应的中断服务程序入口地址为4n,即入口的偏移地址存放在由4n和4n+1指示的存储单元中,入口的段基址存放在由4n+2和4n+3指示的存储单元中。
中断类型号0~31是CPU保留的, 32~255是User Defined.
6. 中断描述符表
在保护模式下,由4个字节的表项构成的中断向量表已经不能满足要求了。在保护模式下,中断向量表中的表项由8个字节组成。此时他也有了新的名字---->中断描述表(Interrupt Descriptor Table,IDT),其中的每个表项叫做一个门描述符(gate descriptor) 。
门类型符主要分为
a.中断门(interrupt gate):其类型码为110,中断门包含了一个中断或异常处理程序所在段的选择符和段内偏移量。
当控制权通过中断门进入中断处理程序时,处理器清IF标志即关中断这样就避免了中断嵌套的发生。
中断门中的DPL(请求特权级)为0,因此用户态中的进程不能访问中断门。所用的中断处理程序都由中断门激活,并全部限制在内核态。
b..陷阱门(tap gate)其类型码为111。它与中断门类似,唯一的区别是控制权通过陷阱门进入处理程序时保持IF标志位不变,即不关中断。
c.系统门(system gate):Linux内核特别设置的,用来让用户态的进程访问Intel的陷阱门。
系统门的DPL为3。系统调用就是通过系统门进入内核的。
在保护模式下,中断描述符表在内存的位置不再局限于从地址0开始的位置,而是可以放在内存的任何位置 。
1>为了实现这个功能--->CPU中设计了一个中断描述符表寄存器IDTR,用来存放中断描述符表在内存的起始位置。
2>中断描述表寄存器是一个48位的寄存器。它的低16为保存中断描述符表的大小,高32位保存中断描述表的基址。
7. 中断处理流程
中断处理的四个过程:中断申请、中断响应、中断处理、中断返回。
1) 中断申请
当外部设备需要中断服务时,有硬件产生一个中断请求信号INT发送给CPU,并且要求INT信号保持到CPU做出响应为止。
2) 中断响应
CPU在每条指令执行结束之后,都会去查询有无中断申请。若查询到有中断请求,并且在允许响应中断的情况下,系统自动进入中断响应周期,有硬件完成关中断、保存断点、去中断服务程序的入口地址等一系列操作,而后转向中断服务程序执行中断处理。
3) 中断处理
中断处理就是执行中断服务程序中规定的操作。在此之前通常要做两件事:
保护现场:使用PUSH指令使相关寄存器的内容入栈,
开中断:目的是为了能够实现中断嵌套。使用指令STI实现。
4) 中断返回
由中断返回指令IRET来完成的。在此之前要使用POP指令将保存的现场信息恢复。
PIC
1. 概念
PIC(Programmable Interrupt Control)可编程中断控制器,通常是指使用两片Intel8259A级联所构成的最多支持15个中断向量的中断控制系统。每个8259A可处理多达 8 个不同的 IRQ。因为从 PIC 的 INT 输出线连接到主 PIC 的 IRQ2 引脚,所以可用 IRQ 线的个数达到 15 个
2. 8259A原理
1)8259A结构图
2) 三个重要的中断状态寄存器
IRR(Interrupt Request Register)中断请求寄存器。
ISR(Interrupt Service Register) 中断服务寄存器。
IMR(Interrupt Mask Register) 中断屏蔽寄存器。
3) 8259A的工作方式
4) 8259A的级联
5) 8259A的编程
8259A有两种工作模式:编程模式和操作模式;
支持两种类型的命令字:初始化命令字(ICW)和操作命令字(OCW)。
6) 8259A的初始化流程
BIOS初始化的时候会先通过向IO Port写入初始化命令字ICW来对8259A进行编程,在此之后8259A就可以响应来自外部设备的中断请求了。
aster的IO Address 是0x20,0x21,IRQ0~IRQ7中断向量号是0x08~0x0F(legacy mode)/0x68~0x6F(Protected mode)。
Slave 的IO Address 是0xA0,0xA1,IRQ8~IRQ15中断向量号是0x70~0x77
ICW1的格式:
ICW2的格式:
ICW3的格式:
主片:
从片:
ICW4的格式:
7) 8259A的操作模式
中断操作编程,是指在8259A工作期间,随时写入操作命令字OCW,来读取状态或者使8259A按照新设置的工作方式进行工作。
OCW1为中断屏蔽字:
OCW2用于设置中断优先级方式和中断结束方式:
OCW3用于设置或清除特殊屏蔽方式和读取寄存器的状态。
8) 与处理器接口
-CS A0 –RD –WR 功能
0 0 1 0 写入ICW1,OCW2,OCW3
0 1 1 0 写入ICW2,ICW3,ICW4,OCW1
0 0 0 1 读出IRR,ISR和查询字
0 1 0 1 读出IMR
0 X 1 1 数据总线高阻状态
1 X X X 数据总线高阻状态
APIC
1. 概念
APIC(Advanced Programmable Interrupt Control)高级可编程中断控制器。
有两部分组成:
IO APIC: 位于南桥中,用于处理桥上的设备所产生的各种中断。它用来接收IO设备所产生的中断,并将其传送给Local APIC。通常有24个输入。
Local APIC:位于CPU中,每个CPU都有一个。负责传送中断至指定的处理器。
2. APIC与PIC的区别:
1)跟PIC一样的是,控制Local APIC 和IO APIC的方法也是通过读写该单元中的相关寄存器。不一样的是,Intel在Local APIC 和IO APIC的寄存器都映射到了物理地址空间:
Local APIC默认映射到物理地址0xFEE0 0000
IO APIC 默认映射到物理地址0xFEC0 0000
2)跟8259A的IRQ pin不一样,中断优先权跟中断输入信号的位置没有任何关系。相反的,Software可以决定每一个Interrupt Input Pin的中断向量、中断优先权、屏蔽位、触发方式、中断管脚的极性、传送方式、传送状态、目的地等,且每个都可以单独设定。
3. IO APIC
1) 实现IO APIC的芯片是82093A。
2) IO APIC的Function:
IO设备要发送一个中断请求,通过触发IO APIC上的Interrupt Line (INTIN0~INTIN23), IO APIC通过重定向表Entry中相应的信息来Format一个中断请求信息发送给Local APIC。
3) IO APIC中重要的Register:
4. Local APIC
1) 存在于CPU中,有几颗CPU就有几个Local APIC。
2) Local APIC两个主要的Function:
一是接收来自于CPU interrupt pin,内部中断源、外部IO APIC所产生的中断,并将它们发送到Processor core去处理。
二是在多处理器系统(MP)中,发送和接受system bus上来自其他处理器的IPI message(Inter-Processor Interrupt).
3) 每个Local APIC由一组APIC寄存器和将中断发送到处理器核心以及生成IPI消息的硬件组成。APIC寄存器是内存映射的,可以使用MOV指令读写。
4) Local APIC可以接收以下中断源所发出的中断:
a. 外部的中断设备
这些IO设备连接到IO APIC的INTIN pin,其产生的中断请求信息通过IO APIC传送到Local APIC
b. 处理器之间的中断(IPI)
Processor通过写ICR(Interrupt Command Register)可以触发IPI。
c. 本地中断源(Local interrupt source),包含五种
1> 本地IO设备
这些IO设备连接到Processor的Local interrupt pin(LINT0/LINT1)或者也可以连接到8259中断控制器,8259又连接到LINT0/LINT1.
2> APIC Timer Interrupt(APIC定时器中断)
3> Performance Monitor Counter Interrupt(性能监视计数器中断)
4> Thermal Sensor Interrupt(温度传感器中断)
5> APIC Internal Error Interrupt(APIC内部错误中断)
Local APIC接收到这五类本地中断源发送过来的中断之后,会根据本地中断向量表LVT(Local Vector Table)所设定的Interrupt delivery protocol来把中断信息传送给processor core。
Address: 0xFEE00330~0xFEE00370
5) 如何判断Local APIC存在与否?
MOV EAX,1
CPUID
返回EDX bit9=1,则存在;bit9=0,则不存在
6) 如何Enable/Disable Local APIC?
两种方式:
1. APIC global enable/disable flag in MSR IA32_APIC_BASE
2. APIC software enable/disable flag in 0xFEE0 00F0
区别:Global Disable之后,只有当下一次Power Up或是Reset之后,Local APIC才能被重新Enable。
Software enable/disable只有在Global Enable的时候才能设置。
5. APIC架构的版本
1> APIC
Pentium/P6系列CPU使用,Local APIC与IO APIC之间通过APIC BUS通信。
2> xAPIC
Pentium4/Xeon系列CPU使用,Local APIC与IO APIC之间通过System BUS通信,xAPIC是APIC架构中一些功能的扩展或修改。
3>x2APIC
是xAPIC的扩展,主要是扩展Processor addressability.