Last updated
Last updated
中断描述符表(也可简称为保护模式下的中断向量表)中一个表项占多少字节?其中哪几位代表中断处理代码的入口?
请编程完善kern/trap/trap.c中对中断向量表进行初始化的函数idt_init。在idt_init函数中,依次对所有中断入口进行初始化。使用mmu.h中的SETGATE宏,填充idt数组内容。每个中断的入口由tools/vectors.c生成,使用trap.c中声明的vectors数组即可。
请编程完善trap.c中的中断处理函数trap,在对时钟中断进行处理的部分填写trap函数中处理时钟中断的部分,使操作系统每遇到100次时钟中断后,调用print_ticks子程序,向屏幕上打印一行文字”100 ticks”。
什么是中断描述符表
中断描述符表(Interrupt Descriptor Table,IDT)将每个异常或中断向量分别与它们的处理过程联系起来。与GDT和LDT表类似,IDT也是由8字节长描述符组成的一个数组。
中断描述符表中一个表项占多少字节
参考代码
由代码可知,中断描述符表idt
的类型为struct gatedesc
,其定义为
所占位数为: 16 + 16 + 5 + 3 + 4 + 1 + 2 + 1 + 16 = 64 bit
所占字节数为: 64 / 8 = 8 byte
中断描述符表中哪几位代表中断处理代码的入口
由struct gatedesc
代码注释可知,第1-16位与48-64位构成段偏移,第17-32位为段选择子,两者联合可计算出入口地址
什么是中断向量表?
在x86架构上,中断向量表(Interrupt Vector Table, IVT)是一个表,用于指定在实模式下使用的所有256个中断处理程序的地址。
IVT通常位于0000:0000H处,大小为400H字节(每个中断4字节)。尽管可以在较新的CPU上使用LIDT指令更改默认地址,但是通常不这样做,因为它不方便且与其他实现和/或较旧的软件(例如MS-DOS程序)不兼容。但是,请注意,代码必须保留在RAM的第一个MiB中。
什么是IDT?
中断描述符表(Interrupt Description Table, IDT)是特定于IA-32体系结构。它是实模式中断向量表(IVT)的保护模式副本,它告诉中断服务例程(Interrupt Service Routines, ISR)所在的位置(每个中断向量一个)。它的结构类似于全局描述符表。
IDT条目称为门。它可以包含中断门,任务门和陷阱门。
在实施IDT之前,请确保您具有有效的GDT。
如何对中断向量表进行初始化?
我们先看该实验的说明:
由该说明我们可以看出,需要做的第一步是将vector.S
作为中断向量引入代码内,说明中已经给出提示,使用extern uintptr_t __vectors[];
即可。
第二步则是对IDT进行初始化,即对变量idt
进行设置,这里提示我们使用宏SETGATE
来设置IDT的每一项。
我们先来看SETGATE
及其说明:
我们刚打开trap.c
文件的时候,就可以看到,变量idt
其实是空的:
在SETGATE
中也可以看出,这个宏一直在修改参数gate
的值,对比该参数的成员以及idt
的类型struct gatedesc
,很明显就可以得知,要传入的第一个参数就是idt
了。
再看第二个参数istrap
的解释,传入1
表示这是一个trap
,等效于exception
,传入0
表示这是一个interrupt gate
,所以对所有的中断,我们要传入的就是0
了。
注:此处有争议,具体见参考文献SETGATE宏的第二个参数istrap的设置。
第三个参数sel
指的是代码段选择子,看到这个就会联想到GDT表中也设置过相关的东西。这里的描述可能有点不太清楚,但是经过一番追查,我们可以找到memlayout.h
,查看注释可以了解到,SEG
开头的是段代码,GD
开头的是段描述符,那么很显然我们应该选择的是GD
开头的了。
然后是具体的描述符的选择,这里要求是代码段,排出以DATA
结尾的数据段选择子,然后现在是处于内核态,排除GD_UTEXT
,可以得知这里应该选择的是GD_KTEXT
了。
接着是需要执行代码的偏移off
,中断需要执行的当然是中断向量咯,所以这里我们选择使用__vectors
变量。
最后一个是调用该中断需要的特权级,即特权级描述符DPL,我们刚才在追查memlayout.h
时也有发现,这里定义了DPL_KERNEL
和DPL_USER
,作为内核态的中断,应该只允许内核调用,不允许用户调用,当然应该选择DPL_KERNEL
。
SETGATE
完成之后,不要忘记执行一下lidt
指令。那么说到这里,需要编写的代码就呼之欲出了。
注:更详细的解释见参考文献中piazza里陈老师的回答。
如何对时钟中断进行处理?
根据提示,我们很容易就能在该位置写出以上代码。
很简单吗?
是的,非常简单。