初始化IDT

task3:完成IDT相关初始化。

(这里再次提醒,请一定通读和理解所有框架代码,否则很难完成任务!!!)

掌控全局

我们可以在idt.c里面看到IDT初始化函数:initIdt。

在这个文件里,我们发现有一个全局变量,是GateDescriptor数组,这就是我们至关重要的IDT。是否还记得下面这个图?前面基础知识部分讲过的。我们要根据这个结构填充setIntr函数和setTrap函数

                              80386 INTERRUPT GATE
 31                23                15                7                0
+-----------------+-----------------+---+---+---------+-----+-----------+
|           OFFSET 31..16           | P |DPL|0 1 1 1 0|0 0 0|(NOT USED) |4
|-----------------------------------+---+---+---------+-----+-----------|
|             SELECTOR              |           OFFSET 15..0            |0
+-----------------+-----------------+-----------------+-----------------+

                              80386 TRAP GATE
 31                23                15                7                0
+-----------------+-----------------+---+---+---------+-----+-----------+
|          OFFSET 31..16            | P |DPL|0 1 1 1 1|0 0 0|(NOT USED) |4
|-----------------------------------+---+---+---------+-----+-----------|
|             SELECTOR              |           OFFSET 15..0            |0
+-----------------+-----------------+-----------------+-----------------+

这两个set函数传递的参数有如下几个:

  • ptr:门描述符的指针,可以通过它来访问对应的结构体!

  • selector:需要填充的选择子(注意!!!这里有坑,请回忆Selector的结构。我们在memory.h里帮你实现了两个宏KSEL和USEL)。

  • offset:与中断对应的处理函数地址(段内偏移)。

  • dpl:最后是DPL。硬件中断(即除了int指令之外的中断)不受DPL影响,8259A的15个中断都为内核级可以禁止用户程序用int指令模拟硬件中断!!!而syscall对应的门描述符的dpl......

exercise15:到这里,我们对中断处理程序是没什么概念的,所以请查看doirq.S,你就会发现idt.c里面的中断处理程序,请回答:所有的函数最后都会跳转到哪个函数?请思考一下,为什么要这样做呢?

我们看一下doirq.S里面的asmDoirq函数,会发现它有一个很奇怪的行为:把esp压进栈

不要着急!注释里面说了:esp is treated as a parameter。那么是什么的参数呢?

exercise16:请问doirq.S里面asmDoirq函数里面为什么要push esp?这是在做什么?(注意在push esp之前还有个pusha,在pusha之前......)

对于Intr和Trap

很多同学对哪些中断设置成Intr,哪些设置成Trap会很有疑惑。

这里建议把keyboard设置成Intr,否则如果快速按键的话可能会出现连续中断嵌套的问题;同时syscall指令也可以设置成Intr,以防止被打断。其余均可设置成Trap。

exercise17:请说说如果keyboard中断出现嵌套,会发生什么问题?(Hint:屏幕会显示出什么?堆栈会怎么样?)

对于键盘中断

要想加上键盘中断的处理,首先要在IDT表中加上键盘中断对应的门描述符,根据前文,8259a将硬件中断映射到键盘中断的向量号0x20-0x2F,键盘为IRQ1,所以键盘中断号为0x21,框架代码也提供了键盘中断的处理函数irqKeyboard

Last updated