第8章 设置IDT(中断描述符表)

步骤:

  1. 设置IDT表 可以参考《Inter微处理器 第8版》p545
  2. 加载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();
}

Leave a Reply

Your email address will not be published. Required fields are marked *