系统调用为0x80中断
(1)初始化8259(arch/i386/boot/setup.S)
设置8259 IRQ0~IRQ15中断向量为0x20~0x2F
8259初始化代码:
mov al,#0x11 ! initialization sequence
out #0x20,al ! send it to 8259A-1
call delay
out #0xA0,al ! and to 8259A-2
call delay
mov al,#0x20 ! start of hardware int's (0x20)
out #0x21,al
call delay
mov al,#0x28 ! start of hardware int's 2 (0x28)
out #0xA1,al
call delay
mov al,#0x04 ! 8259-1 is master
out #0x21,al
call delay
mov al,#0x02 ! 8259-2 is slave
out #0xA1,al
call delay
mov al,#0x01 ! 8086 mode for both
out #0x21,al
call delay
out #0xA1,al
call delay
mov al,#0xFF ! mask off all interrupts for now
out #0xA1,al
call delay
mov al,#0xFB ! mask all irq's but irq2 which
out #0x21,al ! is cascaded
(2) 初始化中断向量表(arch/i386/kernel/head.S)
系统共IDT_ENTRIES(256)个中断描述符(IDT)。初始化时,先用lidt idt_descr把中断向量实际地址装入IDTR寄存器,再将所有中断处理函数指向ignore_int。
IDT结构
BYTE 说明 初始值
0~1 OFFSET ignore_int(输出“Unknown interrupt”)
2~3 SELECTOR(段选择) 0x0010
4~5 P(有效标识1位)DPL(特权级2位) 0 0x0E00 0x8E00(中断描述符有效,特权00,最高)
6~7 OFFSET 0
中断向量表初始化代码:
/*
* 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 */
//eax=ignore_int 0010
movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
lea SYMBOL_NAME(idt_table),%edi
mov $256,%ecx
rp_sidt:
movl %eax,(%edi)
movl %edx,4(%edi)
addl $8,%edi
dec %ecx
jne rp_sidt
ret
ENTRY(stack_start