Skip to content

Latest commit

 

History

History
33 lines (26 loc) · 4.7 KB

idt.md

File metadata and controls

33 lines (26 loc) · 4.7 KB

title: 中断描述符idt date: 2015-01-30 12:05:01 tags: 操作系统 categories: code

#1. IDT# ​在实地址模式中,CPU 把内存中从0 开始的1K 字节作为一个中断向量表。表中的每个表项占4 个字节,由两个字节的段基址和两个字节的偏移量组成,这样构成的地址便是相应中断处理程序的入口地址。在保护模式下,中断向量表中的表项由8 个字节组成,如图3.2 所示,中断向量表也改叫做中断描述符表IDT(Interrupt Descriptor Table)。其中的每个表项叫做一个门描述符(Gate Descriptor),“门”的含义是当中断发生时必须先通过这些门,然后才能进入相应的处理程序。

其中类型占3 位,表示门描述符的类型,这些描述符如下。

1.任务门(Task gate) 其类型码为101,门中包含了一个进程的TSS 段选择符,但偏移量部分没有使用,因为TSS本身是作为一个段来对待的,因此,任务门不包含某一个入口函数的地址。TSS 是Intel 所提供的任务切换机制,但是 Linux 并没有采用任务门来进行任务切换。

2.中断门(Interrupt gate) 其类型码为110,中断门包含了一个中断或异常处理程序所在段的选择符和段内偏移量。当控制权通过中断门进入中断处理程序时,处理器清IF 标志,即关中断,以避免嵌套中断的发生。中断门中的DPL(Descriptor Privilege Level)为0,因此,用户态的进程不能访问Intel 的中断门。所有的中断处理程序都由中断门激活,并全部限制在内核态。

3.陷阱门(Trap gate)
其类型码为111,与中断门类似,其唯一的区别是,控制权通过陷阱门进入处理程序时维持IF 标志位不变,也就是说,不关中断。

4.系统(调用)门(System gate) 这是Linux 内核特别设置的,用来让用户态的进程访问Intel 的陷阱门,因此,门描述符的DPL 为3。通过系统门来激活4 个Linux 异常处理程序,它们的向量是3、4、5 及128,也就是说,在用户态下,可以使用int 3、into、bound 及int 0x80 四条汇编指令。

最后,在保护模式下,中断描述符表在内存的位置不再限于从地址0 开始的地方,而是可以放在内存的任何地方。为此,CPU 中增设了一个中断描述符表寄存器IDTR,用来存放中断描述符表在内存的起始地址。中断描述符表寄存器IDTR 是一个48 位的寄存器,其低16位保存中断描述符表的大小,高32 位保存IDT 的基址,如图所示。
#2. 中断和异常处理# 当CPU 执行了当前指令之后,CS 和EIP 这对寄存器中所包含的内容就是下一条将要执行指令的逻辑地址。在对下一条指令执行前,CPU 先要判断在执行当前指令的过程中是否发生了中断或异常。如果发生了一个中断或异常,那么CPU 将做以下事情。
• 确定所发生中断或异常的向量 i(在0~255 之间)。
• 通过IDTR 寄存器找到IDT 表,读取IDT 表第 i 项(或叫第i 个门)。
• 分两步进行有效性检查:首先是“段”级检查,将CPU 的当前特权级CPL(存放在CS寄存器的最低两位)与IDT 中第 i 项中的段选择符中的RPL 相比较,如果RPL(3)大于CPL(0),就产生一个“通用保护”异常(中断向量13),因为中断处理程序的特权级不能低于引起中断的程序的特权级。这种情况发生的可能性不大,因为中断处理程序一般运行在内核态,其特权级为0。然后是“门”级检查,把CPL 与IDT 中第 i 个门的DPL 相比较,如果CPL (3)大于DPL(0),CPU 就不能“穿过”这个门,于是产生一个“通用保护”异常,这是为了避免用户应用程序访问特殊的陷阱门或中断门。但是请注意,这种检查是针对一般的用户程序引起的中断(INT 指令),而不包括外部I/O 产生的中断或因CPU内部异常而产生的异常,也就是说,如果产生了中断或异常,就免去了“门”级检查。
• 检查是否发生了特权级的变化。若中断发生时CPU运行在用户空间,而中断处理程序运行在内核态,特权级发生了变化,所以会引起堆栈的更换。也就是说,从用户堆栈切换到内核堆栈。而当中断发生在内核态时,即CPU 在内核中运行时,则不会更换堆栈。
CS : EIP 的值就是IDT 表中第i 项门描述符的段选择符和偏移量的值,此时,CPU 就跳转到了中断或异常处理程序。