diff --git a/Makefile b/Makefile index c58a856a..1702e3f4 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ install: kernel cp kernel /mnt/kernel umount /mnt -kernel: start.o link.ld main.o vga.o gdt.o idt.o +kernel: start.o link.ld main.o vga.o gdt.o idt.o isrs.o ld -m elf_i386 -T link.ld -o kernel *.o %.o: %.c diff --git a/bootdisk.img b/bootdisk.img index 94d9acca..b54db2b8 100644 Binary files a/bootdisk.img and b/bootdisk.img differ diff --git a/idt.c b/idt.c index a7dbccbb..f05e0c36 100644 --- a/idt.c +++ b/idt.c @@ -26,7 +26,7 @@ extern void idt_load(); * Set an IDT gate */ void -set_idt_gate( +idt_set_gate( unsigned char num, unsigned long base, unsigned short sel, diff --git a/include/system.h b/include/system.h index b3bd319e..30222938 100644 --- a/include/system.h +++ b/include/system.h @@ -20,4 +20,16 @@ extern void init_video(); extern void gdt_install(); extern void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran); +/* IDT */ +extern void idt_install(); +extern void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags); + +/* Registers */ +struct regs { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int int_no, err_code; + unsigned int eip, cs, eflags, useresp, ss; +}; + #endif diff --git a/isrs.c b/isrs.c new file mode 100644 index 00000000..f952d2e8 --- /dev/null +++ b/isrs.c @@ -0,0 +1,117 @@ +#include + +/* + * Exception Handlers + */ +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(); + +void +isrs_install() { + /* Exception Handlers */ + 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); + 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); +} + +unsigned char *exception_messages[] = { + "division by zero", + "debug", + "non-maskable interrupt", + "breakpoint", + "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" +}; + +void fault_handler(struct regs *r) { + if (r->int_no < 32) { + puts(exception_messages[r->int_no]); + puts(" exception. System halted.\n"); + for (;;); + } +} diff --git a/main.c b/main.c index 6b2d6c80..4ea16b99 100644 --- a/main.c +++ b/main.c @@ -103,6 +103,7 @@ int main() { gdt_install(); idt_install(); + isrs_install(); init_video(); puts("Good Morning!\n"); for (;;); diff --git a/start.asm b/start.asm index 097beadc..fcd5e22b 100644 --- a/start.asm +++ b/start.asm @@ -54,7 +54,282 @@ idt_load: ret ; Interrupt Service Routines +global _isr0 +global _isr1 +global _isr2 +global _isr3 +global _isr4 +global _isr5 +global _isr6 +global _isr7 +global _isr8 +global _isr9 +global _isr10 +global _isr11 +global _isr12 +global _isr13 +global _isr14 +global _isr15 +global _isr16 +global _isr17 +global _isr18 +global _isr19 +global _isr20 +global _isr21 +global _isr22 +global _isr23 +global _isr24 +global _isr25 +global _isr26 +global _isr27 +global _isr28 +global _isr29 +global _isr30 +global _isr31 +; 0: Divide By Zero Exception +_isr0: + cli + push byte 0 + push byte 0 + jmp isr_common_stub + +; 1: Debug Exception +_isr1: + cli + push byte 0 + push byte 1 + jmp isr_common_stub + +; 2: Non Maskable Interrupt Exception +_isr2: + cli + push byte 0 + push byte 2 + jmp isr_common_stub + +; 3: Int 3 Exception +_isr3: + cli + push byte 0 + push byte 3 + jmp isr_common_stub + +; 4: INTO Exception +_isr4: + cli + push byte 0 + push byte 4 + jmp isr_common_stub + +; 5: Out of Bounds Exception +_isr5: + cli + push byte 0 + push byte 5 + jmp isr_common_stub + +; 6: Invalid Opcode Exception +_isr6: + cli + push byte 0 + push byte 6 + jmp isr_common_stub + +; 7: Coprocessor Not Available Exception +_isr7: + cli + push byte 0 + push byte 7 + jmp isr_common_stub + +; 8: Double Fault Exception (With Error Code!) +_isr8: + cli + push byte 8 + jmp isr_common_stub + +; 9: Coprocessor Segment Overrun Exception +_isr9: + cli + push byte 0 + push byte 9 + jmp isr_common_stub + +; 10: Bad TSS Exception (With Error Code!) +_isr10: + cli + push byte 10 + jmp isr_common_stub + +; 11: Segment Not Present Exception (With Error Code!) +_isr11: + cli + push byte 11 + jmp isr_common_stub + +; 12: Stack Fault Exception (With Error Code!) +_isr12: + cli + push byte 12 + jmp isr_common_stub + +; 13: General Protection Fault Exception (With Error Code!) +_isr13: + cli + push byte 13 + jmp isr_common_stub + +; 14: Page Fault Exception (With Error Code!) +_isr14: + cli + push byte 14 + jmp isr_common_stub + +; 15: Reserved Exception +_isr15: + cli + push byte 0 + push byte 15 + jmp isr_common_stub + +; 16: Floating Point Exception +_isr16: + cli + push byte 0 + push byte 16 + jmp isr_common_stub + +; 17: Alignment Check Exception +_isr17: + cli + push byte 0 + push byte 17 + jmp isr_common_stub + +; 18: Machine Check Exception +_isr18: + cli + push byte 0 + push byte 18 + jmp isr_common_stub + +; 19: Reserved +_isr19: + cli + push byte 0 + push byte 19 + jmp isr_common_stub + +; 20: Reserved +_isr20: + cli + push byte 0 + push byte 20 + jmp isr_common_stub + +; 21: Reserved +_isr21: + cli + push byte 0 + push byte 21 + jmp isr_common_stub + +; 22: Reserved +_isr22: + cli + push byte 0 + push byte 22 + jmp isr_common_stub + +; 23: Reserved +_isr23: + cli + push byte 0 + push byte 23 + jmp isr_common_stub + +; 24: Reserved +_isr24: + cli + push byte 0 + push byte 24 + jmp isr_common_stub + +; 25: Reserved +_isr25: + cli + push byte 0 + push byte 25 + jmp isr_common_stub + +; 26: Reserved +_isr26: + cli + push byte 0 + push byte 26 + jmp isr_common_stub + +; 27: Reserved +_isr27: + cli + push byte 0 + push byte 27 + jmp isr_common_stub + +; 28: Reserved +_isr28: + cli + push byte 0 + push byte 28 + jmp isr_common_stub + +; 29: Reserved +_isr29: + cli + push byte 0 + push byte 29 + jmp isr_common_stub + +; 30: Reserved +_isr30: + cli + push byte 0 + push byte 30 + jmp isr_common_stub + +; 31: Reserved +_isr31: + cli + push byte 0 + push byte 31 + jmp isr_common_stub + +extern fault_handler + +isr_common_stub: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, fault_handler + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret ; BSS Section SECTION .bss