x86 kernel 中断机制分析一——IDT

本篇主要分析IDT的初始化流程。

IDT简介

IDT——interrupt description table,用来描述中断异常向量,表中的每一个entry对应一个向量。

IDT entry:

这里写图片描述

每个entry为8bytes,有以下关键bit:
16~31:code segment selector
0~15 & 46-64:segment offset (根据以上两项可确定中断处理函数的地址)
Type:区分中断门、陷阱门、任务门等
DPL:Descriptor Privilege Level, 访问特权级
P:该描述符是否在内存中

desc_struct :

kernel中描述IDT entry的数据结构为

87 typedef struct desc_struct gate_desc;

 14 /*
 15  * FIXME: Accessing the desc_struct through its fields is more elegant,
 16  * and should be the one valid thing to do. However, a lot of open code
 17  * still touches the a and b accessors, and doing this allow us to do it
 18  * incrementally. We keep the signature as a struct, rather than an union,
 19  * so we can get rid of it transparently in the future -- glommer
 20  */
 21 /* 8 byte segment descriptor */
 22 struct desc_struct {
 23     union {
 24         struct {
 25             unsigned int a;
 26             unsigned int b;
 27         };
 28         struct {
 29             u16 limit0;
 30             u16 base0;
 31             unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;
 32             unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
 33         };
 34     };
 35 } __attribute__((packed));

idt_table:

kernel中描述IDT:

 77 /* Must be page-aligned because the real IDT is used in a fixmap. */
 78 gate_desc idt_table[NR_VECTORS] __page_aligned_bss;

初始化IDT

setup_once:

第一次初始化,通过汇编形式,这里应该是设置特权级别和code segment?对汇编就不做太多研究了。

470 /*
471  *  setup_once
472  *
473  *  The setup work we only want to run on the BSP.
474  *
475  *  Warning: %esi is live across this function.
476  */
477 __INIT
478 setup_once:
479     /*
480      * Set up a idt with 256 interrupt gates that push zero if there
481      * is no error code and then jump to early_idt_handler_common.
482      * It doesn't actually load the idt - that needs to be done on
483      * each CPU. Interrupts are enabled elsewhere, when we can be
484      * relatively sure everything is ok.
485      */
486
487     movl $idt_table,%edi
488     movl $early_idt_handler_array,%eax
489     movl $NUM_EXCEPTION_VECTORS,%ecx
490 1:
491     movl %eax,(%edi)
492     movl %eax,4(%edi)
493     /* interrupt gate, dpl=0, present */
494     movl $(0x8E000000 + __KERNEL_CS),2(%edi)
495     addl $EARLY_IDT_HANDLER_SIZE,%eax
496     addl $8,%edi
497     loop 1b
498
499     movl $256 - NUM_EXCEPTION_VECTORS,%ecx
500     movl $ignore_int,%edx
501     movl $(__KERNEL_CS << 16),%eax
502     movw %dx,%ax        /* selector = 0x0010 = cs */
503     movw $0x8E00,%dx    /* interrupt gate - dpl=0, present */
504 2:
505     movl %eax,(%edi)
506     movl %edx,4(%edi)
507     addl $8,%edi
508     loop 2b

early_trap_init:

第二次初始化,通过early_trap_init和trap_init初始化IDT中kernel保留的vector,比如前32个vector和system call(0x80)等。系统保留的向量和set_intr_gate等分析见附录。


                
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值