购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4.2 设置中断描述符表

本章已经详细地介绍了IDT和中断描述符(ID)的结构,进入到保护模式以后,需要在内核里为CPU内核设置一个包含256个中断描述符的IDT,具体实现如代码清单2-10所示。

代码清单2-10 设置IDT(head.S)

1  .code32

2  .text

3  .globl startup_32

4  startup_32:

5    movl $0x10,%eax

6    movw %ax, %ds

7    movw %ax, %es

8    movw %ax, %fs

9    movl $0x18,%eax 10movw %ax,%gs

11

12   call setup_idt

13   int $0x80

14

15   movl $0x18, %eax

16   movw %ax,%gs

17   movl $0x0,%edi

18   movb $0xf,%ah

19   movb $0x42,%al

20   movw %ax,%gs:(%edi)

21

22 loop:

23   jmploop

24

25 setup_idt:

26   leal ignore_int,%edx

27   movl $0x00080000, %eax

28   movw %dx,%ax

29   movw $0x8e00,%dx

30   leal idt,%edi

31   movl $256,%ecx

32 rp_sidt:

33   movl %eax,(%edi)

34   movl%edx,4(%edi)

35   addl $8,%edi

36   decl%ecx

37   jnerp_sidt

38   lidt idt_descr

39   ret

40

41 ignore_int:

42   /* 我们现在还没有printk函数,通过向显存直接写入字符来模拟它 */

43   pushl %eax

44   pushl %ecx

45   pushl %edx

46   pushw %ds

47   pushw %es

48   pushw %fs

49   movl $0x10, %eax

50   movw %ax,%ds

51   movw %ax,%es

52   movw %ax,%fs

53   /* 调用printk函数 */

54   movl $0x96,%edi

55   movb $'I', %al

56   movb $0x0c, %ah

57   movw %ax, %gs:(%edi)

58   popw %fs

59   popw %es

60   popw %ds

61   popl %edx

62   popl %ecx

63   popl %eax

64   iret

65

66 .align 4

67 .word 0

68 idt_descr:

69   .word 256 *8-1

70 .long idt

71

72 idt:

73   .fill 256,8,0

首先,第73行声明了一个包含256个元素,每个元素的宽度都是8B,且其值为0的数组,这就是内核所要使用的IDT。接下来,就是初始化IDT的过程,第12行调用了setup_idt这一段子程序,从第25行到39行是setup_idt子程序的定义。

setup_idt子程序先初始化中断描述符,并将它保存到edx、eax寄存器中,其中描述符中的中断服务程序都指向了ignore_int。接下来通过rp_sidt循环了256次,将IDT的256项都设置成相同的中断描述符(读者可以根据图2-10自己分析中断描述符的结构)。这样一来,不管发生什么中断,CPU都会转而调用ignore_int这个中断服务程序。

而ignore_int的实现则是在屏幕第1行的靠右位置(0x96/2=0x4b)处打印红色的字母I。这里要注意的是,所有的中断服务程序要遵循开始时保存上下文,结束后恢复上下文的规定。中断服务程序的最后,一定是iret指令,用于恢复到中断发生之前的程序继续执行。

程序的第13行使用了int $0x80语句进行了实验。这条语句使用了软中断来触发一次CPU中断,看上去它和之前使用的BIOS中断的指令是一样的,但实际上现在已经是保护模式了,它背后的原理和BIOS中断已经大相径庭了。如果一切正常的话,当0x80号中断被触发时,屏幕上就可以正确地显示红色的I了,如图2-13所示。

图2-13 中断服务程序 tT4KbSXseN/XwL2xkVP43is80Xhw+QVln0c9NPUGDTV2pRVE3904ZFK/kfBcTIRT

点击中间区域
呼出菜单
上一章
目录
下一章
×