步骤:
- 设置IDT表 可以参考《Inter微处理器 第8版》p545
- 加载IDT表(只有开中断,它才开始作用)
设置IDT和ISR,idt.c的源代码如下所示
#include "io.h" #include "video.h" #include "kernel.h" #include "asm.h" #include "interrupt.h" unsigned long long IDT[256] = {0}; struct DESCR{ unsigned short length; unsigned long address; }__attribute__((packed)) idt_descr = {256*8-1, (unsigned long )IDT}; static void isr_entry(int index, unsigned long long offset) { //中断门,《intel微处理器 第八版》p544 unsigned long long idt_entry = 0x00008e0000000000ULL | ((unsigned long long)CODE_SEL << 16); idt_entry |= (offset << 32) & 0xffff000000000000ULL; idt_entry |= (offset) & 0xffff; IDT[index] = idt_entry; } void do_default_isr(unsigned long esp, unsigned long error_code) { kprint(0x14,"DEFAULT_ISR!!\n"); halt(); } void idt_install(void) { unsigned int i = 0; //先填充IDT表 for(i = 0; i < 256; i++) { isr_entry(i, (unsigned int )default_isr); } isr_entry(0, (unsigned int)divide_error); isr_entry(1, (unsigned int)debug_exception); isr_entry(2, (unsigned int)nmi); isr_entry(3, (unsigned int)breakpoint); isr_entry(4, (unsigned int)overflow); isr_entry(5, (unsigned int)bound); isr_entry(6, (unsigned int)invalid_opcode); isr_entry(7, (unsigned int)coprocessor_not_available); isr_entry(8, (unsigned int)double_fault); isr_entry(9, (unsigned int)coprocessor_segment_overrun); isr_entry(10, (unsigned int)invalid_tss); isr_entry(11, (unsigned int)segment_not_present); isr_entry(12, (unsigned int)stack_exception); isr_entry(13, (unsigned int)protection_exception); isr_entry(14, (unsigned int)page_fault); isr_entry(15, (unsigned int)intel_reserved); isr_entry(16, (unsigned int)coprecessor_error); isr_entry(0x20, (unsigned int)timer); //IRQ0是时钟中断 //载入idt_descr __asm__("lidt %0\n\t"::"m"(idt_descr)); } void do_divide_error(unsigned long esp, unsigned long error_code) { kprint(0x14, "divide_error"); halt(); } void do_debug_exception(unsigned long esp, unsigned long error_code) { kprint(0x14, "debug_exception"); halt(); } void do_nmi(unsigned long esp, unsigned long error_code) { kprint(0x14, "nmi"); halt(); } void do_breakpoint(unsigned long esp, unsigned long error_code) { kprint(0x14, "breakpoint"); halt(); } void do_overflow(unsigned long esp, unsigned long error_code) { kprint(0x14, "overflow"); halt(); } void do_bound(unsigned long esp, unsigned long error_code) { kprint(0x14, "bound"); halt(); } void do_invalid_opcode(unsigned long esp, unsigned long error_code) { kprint(0x14, "invalid_opcode"); halt(); } void do_coprocessor_not_available(unsigned long esp, unsigned long error_code) { kprint(0x14, "coprocessor_not_available"); halt(); } void do_double_fault(unsigned long esp, unsigned long error_code) { kprint(0x14, "double_fault"); halt(); } void do_coprocessor_segment_overrun(unsigned long esp, unsigned long error_code) { kprint(0x14, "coprocessor_segment_overrun"); halt(); } void do_invalid_tss(unsigned long esp, unsigned long error_code) { kprint(0x14, "invalid_tss"); halt(); } void do_segment_not_present(unsigned long esp, unsigned long error_code) { kprint(0x14, "segment_not_present"); halt(); } void do_stack_exception(unsigned long esp, unsigned long error_code) { kprint(0x14, "stack_exception"); halt(); } void do_protection_exception(unsigned long esp, unsigned long error_code) { kprint(0x14, "protection_exception"); halt(); } void do_page_fault(unsigned long esp, unsigned long error_code) { kprint(0x14, "page_fault"); halt(); } void do_intel_reserved(unsigned long esp, unsigned long error_code) { kprint(0x14, "intel_reserved"); halt(); } void do_coprocessor_error(unsigned long esp, unsigned long error_code) { kprint(0x14, "coprocessor_error"); halt(); }