10)中断初始化

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
// init/main.c
void main(void) {
...
trap_init();
...
}

// kernel/traps.c
void trap_init(void) {
int i;
set_trap_gate(0,&divide_error);
set_trap_gate(1,&debug);
set_trap_gate(2,&nmi);
set_system_gate(3,&int3); /* int3-5 can be called from all */
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,&parallel_interrupt);
}
C

这个函数负责初始化中断,能让系统接收各种事件,比如键盘。

主要有三个部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// kernel/traps.c
void trap_init(void) {
int i;
// set 了一堆 trap_gate
set_trap_gate(0, &divide_error);
...
// 又 set 了一堆 system_gate
set_system_gate(45, &bounds);
...
// 又又批量 set 了一堆 trap_gate
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
// include/asm/system.h
#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


10)中断初始化
https://carl-5535.github.io/2024/08/06/Linux0.11/10)中断初始化/
作者
Carl Chen
发布于
2024年8月6日
许可协议