trap_init
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| void main(void) { ... trap_init(); ... }
void trap_init(void) { int i; set_trap_gate(0,÷_error); set_trap_gate(1,&debug); set_trap_gate(2,&nmi); set_system_gate(3,&int3); set_system_gate(4,&overflow); set_system_gate(5,&bounds); set_trap_gate(6,&invalid_op); set_trap_gate(7,&device_not_available); set_trap_gate(8,&double_fault); set_trap_gate(9,&coprocessor_segment_overrun); set_trap_gate(10,&invalid_TSS); set_trap_gate(11,&segment_not_present); set_trap_gate(12,&stack_segment); set_trap_gate(13,&general_protection); set_trap_gate(14,&page_fault); set_trap_gate(15,&reserved); set_trap_gate(16,&coprocessor_error); for (i=17;i<48;i++) set_trap_gate(i,&reserved); set_trap_gate(45,&irq13); set_trap_gate(39,¶llel_interrupt); }
C
|
这个函数负责初始化中断,能让系统接收各种事件,比如键盘。
主要有三个部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void trap_init(void) { int i; set_trap_gate(0, ÷_error); ... set_system_gate(45, &bounds); ... for (i=17;i<48;i++) set_trap_gate(i, &reserved); ... }
C
|
set_trap_gate 和 set_system_gate
set_trap_gate 和 set_system_gate 是宏定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #define _set_gate(gate_addr,type,dpl,addr) \ __asm__ ("movw %%dx,%%ax\n\t" \ "movw %0,%%dx\n\t" \ "movl %%eax,%1\n\t" \ "movl %%edx,%2" \ : \ : "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ "o" (*((char *) (gate_addr))), \ "o" (*(4+(char *) (gate_addr))), \ "d" ((char *) (addr)),"a" (0x00080000))
#define set_trap_gate(n,addr) \ _set_gate(&idt[n],15,0,addr)
#define set_system_gate(n,addr) \ _set_gate(&idt[n],15,3,addr)
C
|
这种写法是将汇编语言嵌入到 C 语言了,这种内联汇编的格式很难看,知道最终的效果就行。而最终的效果就是在中断描述符表中插入了一个中断描述符。
中断描述符表
中断描述符表,简称idt,前面讲过已经设置了过一次:

这段代码就是往这个 idt 表里一项一项地写东西,其对应的中断号就是第一个参数,中断处理程序就是第二个参数。产生的效果就是,之后如果来了一个中断,CPU 根据其中断号,就可以到这个中断描述符表 idt 中找到对应的中断处理程序了。
所以上面就是将中断号016,45和39设置不同的中断处理函数,中断号1738,40~47设置为临时的中断处理程序reserved
