Understanding the linux kernel-ch4-Initializing the Interrupt Descriptor Table

Interrupt, Trap, and System Gates
Linux uses a slightly different breakdown and terminology from Intel 




when classifying the interrupt descriptors included in the Interrupt Descriptor Table:



Interrupt gate







An Intel interrupt gate that cannot be accessed by a User Mode process 



(the gate's DPL field is equal to 0). All Linux interrupt handlers are activated by means of 


interrupt gates , and all are restricted to Kernel Mode.





System gate








An Intel trap gate that can be accessed by a User Mode process (the gate's DPL field is equal to 3). 

The three Linux exception handlers associated with the vectors 4, 5, and 128 are activated 


by means of system gates , so the three assembly language instructions into , bound ,



 and int $0x80 can be issued in User Mode.






System interrupt gate







An Intel interrupt gate that can be accessed by a User Mode process (the gate's DPL field is equal to 3).

 The exception handler associated with the vector 3 is activated by means of a system interrupt gate, 

so the assembly language instruction int3 can be issued in User Mode.



Trap gate








An Intel trap gate that cannot be accessed by a User Mode process (the gate's DPL field is equal to 0). 

Most Linux exception handlers are activated by means of trap gates 



Task gate








An Intel task gate that cannot be accessed by a User Mode process (the gate's DPL field is equal to 0). 

The Linux handler for the "Double fault " exception is activated by means of a task gate.












The following architecture-dependent functions are used to insert gates in the IDT


set_intr_gate(n,addr)//Inserts an interrupt gate in the n th IDT entry



set_system_gate(n,addr)







set_system_intr_gate(n,addr)






set_trap_gate(n,addr)







set_task_gate(n,gdt)









//i386/kernel/traps.c





static void __init set_system_gate(unsigned int n, void *addr)




{









_set_gate(idt_table+n,15,3,addr,__KERNEL_CS);




}








#define _set_gate(gate_addr,type,dpl,addr,seg) /





do { /








  int __d0, __d1; /







  __asm__ __volatile__ ("movw %%dx,%%ax/n/t" /






movw %4,%%dx/n/t /







movl %%eax,%0/n/t /







movl %%edx,%1 /







:"=m" (*((long *) (gate_addr))), /






 "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) /




:"i" ((short) (0x8000+(dpl<<13)+(type<<8))), /





 "3" ((char *) (addr)),"2" ((seg) << 16)); /




} while (0)




























The IDT is initialized and used by the BIOS routines while the computer still operates in Real Mode.

 Once Linux takes over, however, the IDT is moved to another area of RAM



 and initialized a second time, because Linux does not use any BIOS routine















//i386/kernel/head.s





/*








 *  setup_idt








 *








 *  sets up a idt with 256 entries pointing to





 *  ignore_int, interrupt gates. It doesn't actually load




 *  idt - that can be done only after paging has been enabled




 *  and the kernel moved to PAGE_OFFSET. Interrupts




 *  are enabled elsewhere, when we can be relatively




 *  sure everything is ok.







 */








setup_idt:









lea ignore_int,%edx







movl $(__KERNEL_CS << 16),%eax






movw %dx,%ax/* selector = 0x0010 = cs */




movw $0x8E00,%dx/* interrupt gate - dpl=0, present */















lea idt_table,%edi







mov $256,%ecx






rp_sidt:









movl %eax,(%edi)







movl %edx,4(%edi)







addl $8,%edi







dec %ecx








jne rp_sidt








ret

















/* This is the default interrupt "handler" :-) */





int_msg:









.asciz "Unknown interrupt/n"






ALIGN







ignore_int:









cld








pushl %eax







pushl %ecx







pushl %edx







pushl %es








pushl %ds








movl $(__KERNEL_DS),%eax






movl %eax,%ds







movl %eax,%es







pushl $int_msg







call printk








popl %eax








popl %ds








popl %es








popl %edx








popl %ecx








popl %eax








iret






The ignore_int( ) handler should never be executed. The occurrence of "Unknown interrupt" 

messages on the console or in the log files denotes either a hardware problem 


(an I/O device is issuing unforeseen interrupts) or a kernel problem



 (an interrupt or exception is not being handled properly).     
          
          
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值