struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
(摘自arch/kernel/i386/traps.c)其中每一个表项均是一个desc_struct结构,该结构被定以为:
struct desc_struct {
unsigned long a,b;
};
(摘自/inlcude/asm-i386/processor.h)。可以看出IDT表共256个表项,每一个表项是8个字节,在idt_table数组被定义时静态初始化为0。
关于系统的启动请参见http://blog.chinaunix.net/u2/73528/showart_1132645.html,在setup32_up()函数中,会调用setup_idt()函数初始化IDT,该函数使用AT&T汇编写成,在/arch/i386/kernel/head.S中:
1 setup_idt:
2 lea ignore_int,%edx
3 movl $(__KERNEL_CS << 16),%eax
4 movw %dx,%ax /* selector = 0x0010 = cs */
5 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
6
7 lea idt_table,%edi
8 mov $256,%ecx
9 rp_sidt:
10 movl %eax,(%edi)
11 movl %edx,4(%edi)
12 addl $8,%edi
13 dec %ecx
14 jne rp_sidt
15 .....
16 ret
在第2行将ignore_int函数的地址放入edx寄存器中,第三行将段选择符 加载进eax寄存器的高16位中,第4行是将ignore_int()函数地址的低16位放入eax寄存器的低16位(ax)中,这样就在eax寄存器中组成了idt的低4字节的值,也就是赋给desc_struct->a的值。接下来第5行是将0x8E00放入edx寄存器的低16位中,刚才edx中存放的ignore_int()函数的地址,这样就在edx寄存器中形成了idt的高4字节的值,也就是赋给desc_struct->b的值。第7行将idt_table数组的首地址放入edi寄存器中,第8行是初始化循环计数器ecx为256。第9行是把eax中的内容(32字节)放入edi所指的内存中(也就是idt_table[256-(%ecx)]->a),第11行是将edx中的内容放入edi+4所指的内存中(也就是idt_table[256-(%ecx)]->b)。这样就对idt_table[256-(%ecx)]进行了初始化。第12行是给edi加8使其指向idt_table[256-(%ecx)+1],13行自减计数器ecx,在14行判断如果ecx不为0则跳转至rp_sidt处继续初始化idt_table数组的下一个数据项,直到ecx为0,也就是idt_table数组全部被初始化。
