• zyf's avatar
    update · 3e6ab325
    zyf authored
    3e6ab325
isrs.c 5.09 KiB
/* 
*  描述:中断服务程序安装程序和异常
*/
#include <system.h>
/* 这些是所有异常处理程序的原型:IDT中的前32个条目由Intel保留,
*  设计用于服务异常! */
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();
extern void isr80();
/* 我们将IDT中的前32个条目设置为前32个ISR。我们不能为此使用for循环,
*  因为没有办法获取与给定条目对应的函数名。我们将访问标志设置为0x8E。
*  这意味着条目存在,运行在环0(内核级别),并且将所需的'14'设置为
*  低5位,这在十六进制中表示为'E'。 */
void isrs_install()
    idt_set_gate(0, (unsigned)isr0, 0x08, 0x8E);
    idt_set_gate(1, (unsigned)isr1, 0x08, 0x8E);
    idt_set_gate(2, (unsigned)isr2, 0x08, 0x8E);
    idt_set_gate(3, (unsigned)isr3, 0x08, 0x8E);
    idt_set_gate(4, (unsigned)isr4, 0x08, 0x8E);
    idt_set_gate(5, (unsigned)isr5, 0x08, 0x8E);
    idt_set_gate(6, (unsigned)isr6, 0x08, 0x8E);
    idt_set_gate(7, (unsigned)isr7, 0x08, 0x8E);
    idt_set_gate(8, (unsigned)isr8, 0x08, 0x8E);
    idt_set_gate(9, (unsigned)isr9, 0x08, 0x8E);
    idt_set_gate(10, (unsigned)isr10, 0x08, 0x8E);
    idt_set_gate(11, (unsigned)isr11, 0x08, 0x8E);
    idt_set_gate(12, (unsigned)isr12, 0x08, 0x8E);
    idt_set_gate(13, (unsigned)isr13, 0x08, 0x8E);
    idt_set_gate(14, (unsigned)isr14, 0x08, 0x8E);
    idt_set_gate(15, (unsigned)isr15, 0x08, 0x8E);
    idt_set_gate(16, (unsigned)isr16, 0x08, 0x8E);
    idt_set_gate(17, (unsigned)isr17, 0x08, 0x8E);
    idt_set_gate(18, (unsigned)isr18, 0x08, 0x8E);
    idt_set_gate(19, (unsigned)isr19, 0x08, 0x8E);
    idt_set_gate(20, (unsigned)isr20, 0x08, 0x8E);
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
idt_set_gate(21, (unsigned)isr21, 0x08, 0x8E); idt_set_gate(22, (unsigned)isr22, 0x08, 0x8E); idt_set_gate(23, (unsigned)isr23, 0x08, 0x8E); idt_set_gate(24, (unsigned)isr24, 0x08, 0x8E); idt_set_gate(25, (unsigned)isr25, 0x08, 0x8E); idt_set_gate(26, (unsigned)isr26, 0x08, 0x8E); idt_set_gate(27, (unsigned)isr27, 0x08, 0x8E); idt_set_gate(28, (unsigned)isr28, 0x08, 0x8E); idt_set_gate(29, (unsigned)isr29, 0x08, 0x8E); idt_set_gate(30, (unsigned)isr30, 0x08, 0x8E); idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E); idt_set_gate(0x80, (unsigned)isr80, 0x08, 0x8E | 0x60); } /* 这是一个简单的字符串数组。它包含每个异常对应的消息。 * 我们通过访问如下内容来获取正确的消息: * exception_message[interrupt_number] */ unsigned char *exception_messages[] = { "Division By Zero", "Debug", "Non Maskable Interrupt", "Breakpoint", "Into Detected Overflow", "Out of Bounds", "Invalid Opcode", "No Coprocessor", "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", "Segment Not Present", "Stack Fault", "General Protection Fault", "Page Fault", "Unknown Interrupt", "Coprocessor Fault", "Alignment Check", "Machine Check", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved" }; /* 所有的外部定义的故障处理程序,我们不想让整个内核都能看到它们。 * 可以将这些放在头文件中 */ extern void _page_fault(struct regs* r); /* 我们所有的异常处理中断服务程序都将指向这个函数。 * 这将告诉我们发生了什么异常!现在,我们只是通过进入一个 * 无尽循环来停止系统。所有ISR在服务时都会禁用中断,作为一种 * '锁定'机制,以防止IRQ发生并破坏内核数据结构 */ void _fault_handler(struct regs r) { /* 是否是我们要处理的故障? */ switch (r.int_no) {
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
case 13: return; case 14: /* 页错误;发送到page.c */ page_fault(&r); return; case 80: /* 系统调用;发送到syscall.c */ syscall_handler(&r); return; default: /* 不是我们要特别处理的故障, * 所以让它通过下面的if语句 */ break; } /* 是否是编号为0到31的故障? */ if (r.int_no < 32) { /* 显示发生的异常的描述。 * 在本教程中,我们将简单地使用无限循环来停止系统。 */ putch('\n'); settextcolor(4, 0); puts(exception_messages[r.int_no]); puts(" 异常。\n系统已停止!\n\0"); for (;;); } }