2.5 异常处理类中断服务程序挂接(1)

2.5 异常处理类中断服务程序挂接(1)

不论是用户进程还是系统内核都要经常使用中断或遇到很多异常情况需要处理,如CPU在参与运算过程中,可能会遇到除零错误、溢出错误、边界检查错误、缺页错误……免不了需要“异常处理”。中断技术也是广泛使用的,系统调用就是利用中断技术实现的。这些中断、异常都需要具体的服务程序来执行。trap_init()函数将中断、异常处理的服务程序与IDT进行挂接,逐步重建中断服务体系,支持内核、进程在主机中的运算。挂接的具体过程及异常处理类中断服务程序在IDT中所占用的位置如图2-6所示。

执行代码如下:

 
 
  1. //代码路径:init/main.c:  
  2. void main(void)  
  3. {  
  4.     …  
  5.     trap_init();  
  6.     …  
  7. }  
  8.  
  9. //代码路径:kernel/traps.c:  
  10. void trap_init(void)  
  11. {  
  12.     int i;  
  13.  
  14.     set_trap_gate(0,&divide_error);//除零错误  
  15.     set_trap_gate(1,&debug); //单步调试  
  16.     set_trap_gate(2,&nmi); //不可屏蔽中断  
  17.  
  18.     set_system_gate(3,&int3); /* int3-5 can be called from all */  
  19.     set_system_gate(4,&overflow); //溢出  
  20.     set_system_gate(5,&bounds); //边界检查错误  
  21.     set_trap_gate(6,&invalid_op); //无效指令  
  22.     set_trap_gate(7,&device_not_available); //无效设备  
  23.     set_trap_gate(8,&double_fault); //双故障  
  24.     set_trap_gate(9,&coprocessor_segment_overrun);//协处理器段越界  
  25.     set_trap_gate(10,&invalid_TSS); //无效TSS  
  26.     set_trap_gate(11,&segment_not_present); //段不存在  
  27.     set_trap_gate(12,&stack_segment); //栈异常    
  28.     set_trap_gate(13,&general_protection); //一般性保护异常  
  29.     set_trap_gate(14,&page_fault); //缺页  
  30.     set_trap_gate(15,&reserved); //保留  
  31.     set_trap_gate(16,&coprocessor_error); //协处理器错误  
  32.     for (i=17;i<48;i++) //都先挂接好,中断服务程序函数名初  
  33.  //始化为保留  
  34.          set_trap_gate(i,&reserved);  
  35.     set_trap_gate(45,&irq13); //协处理器  
  36.     outb_p(inb_p(0x21)&0xfb,0x21); //允许IRQ2中断请求  
  37.     outb(inb_p(0xA1)&0xdf,0xA1); // 允许IRQ2中断请求  
  38.     set_trap_gate(39,&parallel_interrupt); //并口  
  39. }  
  40.  
  41. //代码路径:include\asm\system.h:  
  42.     …  
  43. #define _set_gate(gate_addr,type,dpl,addr) \  
  44. __asm__("movw %%dx,%%ax\n\t" \ //将edx的低字赋值给eax的低字  
  45.          "movw %0,%%dx\n\t" \ //%0对应第二个冒号后的第1行的"i"  
  46.          "movl %%eax,%1\n\t" \ //%1对应第二个冒号后的第2行的"o"  
  47.          "movl %%edx,%2" \ //%2对应第二个冒号后的第3行的"o"  
  48.          : \ //这个冒号后面是输出,下面冒号后面  
  49.  //是输入  
  50.     : "i" ((short) (0x8000?+?(dpl<<13)?+?(type<<8))), \ //立即数  
  51.            "o" (*((char *) (gate_addr))), \  //中断描述符前4个字节的地址  
  52.            "o" (*(4?+?(char *) (gate_addr))), \  //中断描述符后4个字节的地址  
  53.            "d" ((char *) (addr)),"a" (0x00080000)) //"d"对应edx,"a"对应eax  
  54.     …  
  55. #define set_trap_gate(n,addr) \  
  56.  _set_gate(&idt[n],15,0,addr) 

这些代码的目的就是要拼出第1章1.3.5节讲述过的中断描述符。为了便于阅读,复制在下面,如图2-7所示。

上述代码的执行效果如图2-8所示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值