From 388834ef8aaead62c99e6e182e8e5a952000b0d7 Mon Sep 17 00:00:00 2001 From: Jenny Curle Date: Sun, 7 Apr 2019 19:25:27 +0100 Subject: [PATCH] Implement ISRs and fault handling --- arch/i386/isr.s | 87 ++++++++++++++++++++++ arch/i386/make.config | 1 + include/kernel/descriptor_tables.h | 14 +++- kernel/isr.c | 115 +++++++++++++++++++++++++++++ kernel/kernel.c | 3 +- makefile | 4 + 6 files changed, 222 insertions(+), 2 deletions(-) create mode 100755 arch/i386/isr.s create mode 100755 kernel/isr.c diff --git a/arch/i386/isr.s b/arch/i386/isr.s new file mode 100755 index 0000000..1a08674 --- /dev/null +++ b/arch/i386/isr.s @@ -0,0 +1,87 @@ +%macro ISR 1 + global isr%1 + isr%1: + cli + push byte 0 + push byte %1 + jmp isr_common +%endmacro + +%macro ISR_ERR 1 + global isr%1 + isr%1: + cli + push byte %1 + jmp isr_common +%endmacro + +%macro IRQ 2 + global irq%1 + irq%1: + cli + push byte 0 + push byte %2 + jmp isr_common +%endmacro + +ISR 0 +ISR 1 +ISR 2 +ISR 3 +ISR 4 +ISR 5 +ISR 6 +ISR 7 +ISR_ERR 8 +ISR 9 +ISR_ERR 10 +ISR_ERR 11 +ISR_ERR 12 +ISR_ERR 13 +ISR_ERR 14 +ISR 15 +ISR 16 +ISR_ERR 17 +ISR 18 +ISR 19 +ISR 20 +ISR 21 +ISR 22 +ISR 23 +ISR 24 +ISR 25 +ISR 26 +ISR 27 +ISR 28 +ISR 29 +ISR_ERR 30 +ISR 31 + + +extern fault_handler + +isr_common: + 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 diff --git a/arch/i386/make.config b/arch/i386/make.config index 157deaa..a5f7c22 100755 --- a/arch/i386/make.config +++ b/arch/i386/make.config @@ -6,4 +6,5 @@ KERNEL_ARCH_LIBS= KERNEL_ARCH_OBJS= \ $(ARCHDIR)/boot.o \ $(ARCHDIR)/gdt.o \ +$(ARCHDIR)/isr.o \ $(ARCHDIR)/tty.o \ No newline at end of file diff --git a/include/kernel/descriptor_tables.h b/include/kernel/descriptor_tables.h index 1d71852..4ba9ce3 100755 --- a/include/kernel/descriptor_tables.h +++ b/include/kernel/descriptor_tables.h @@ -1,7 +1,19 @@ #pragma once +#include +#include + void gdt_set_gate(int, unsigned long, unsigned long, unsigned char, unsigned char); void gdt_install(); void idt_set_gate(unsigned char, unsigned long, unsigned short, unsigned char); -void idt_install(); \ No newline at end of file +void idt_install(); + +typedef struct registers { + uint32_t ds; + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; + uint32_t int_no, err_code; + uint32_t eip, cs, eflags, useresp, ss; +} registers_t; + +void isr_install(); \ No newline at end of file diff --git a/kernel/isr.c b/kernel/isr.c new file mode 100755 index 0000000..c3c7e6f --- /dev/null +++ b/kernel/isr.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +//These are all reserved by Intel, and need to be here. +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 isr_install() { + idt_set_gate(0, (unsigned)isr0, 0x00, 0x8E); + idt_set_gate(1, (unsigned)isr1, 0x00, 0x8E); + idt_set_gate(2, (unsigned)isr2, 0x00, 0x8E); + idt_set_gate(3, (unsigned)isr3, 0x00, 0x8E); + idt_set_gate(4, (unsigned)isr4, 0x00, 0x8E); + idt_set_gate(5, (unsigned)isr5, 0x00, 0x8E); + idt_set_gate(6, (unsigned)isr6, 0x00, 0x8E); + idt_set_gate(7, (unsigned)isr7, 0x00, 0x8E); + idt_set_gate(8, (unsigned)isr8, 0x00, 0x8E); + idt_set_gate(9, (unsigned)isr9, 0x00, 0x8E); + idt_set_gate(10, (unsigned)isr10, 0x00, 0x8E); + idt_set_gate(11, (unsigned)isr11, 0x00, 0x8E); + idt_set_gate(12, (unsigned)isr12, 0x00, 0x8E); + idt_set_gate(13, (unsigned)isr13, 0x00, 0x8E); + idt_set_gate(14, (unsigned)isr14, 0x00, 0x8E); + idt_set_gate(15, (unsigned)isr15, 0x00, 0x8E); + idt_set_gate(16, (unsigned)isr16, 0x00, 0x8E); + idt_set_gate(17, (unsigned)isr17, 0x00, 0x8E); + idt_set_gate(18, (unsigned)isr18, 0x00, 0x8E); + idt_set_gate(19, (unsigned)isr19, 0x00, 0x8E); + idt_set_gate(20, (unsigned)isr20, 0x00, 0x8E); + idt_set_gate(21, (unsigned)isr21, 0x00, 0x8E); + idt_set_gate(22, (unsigned)isr22, 0x00, 0x8E); + idt_set_gate(23, (unsigned)isr23, 0x00, 0x8E); + idt_set_gate(24, (unsigned)isr24, 0x00, 0x8E); + idt_set_gate(25, (unsigned)isr25, 0x00, 0x8E); + idt_set_gate(26, (unsigned)isr26, 0x00, 0x8E); + idt_set_gate(27, (unsigned)isr27, 0x00, 0x8E); + idt_set_gate(28, (unsigned)isr28, 0x00, 0x8E); + idt_set_gate(29, (unsigned)isr29, 0x00, 0x8E); + idt_set_gate(30, (unsigned)isr30, 0x00, 0x8E); + idt_set_gate(31, (unsigned)isr31, 0x00, 0x8E); +} + +const 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" +}; + +void fault_handler(registers_t *r) { + if(r->int_no < 32) { + term_write(exception_messages[r->int_no], strlen(exception_messages[r->int_no])); + puts(" Exception. Halting."); + for(;;); + } +} \ No newline at end of file diff --git a/kernel/kernel.c b/kernel/kernel.c index ad7d45f..6b61f30 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -19,7 +19,8 @@ int kernel_main(void) { // Prepare interrupts serial_print(0x3F8, "[INFO] Beginning IDT subroutine.\n"); - idt_install(); + idt_install(); + isr_install(); //Print a copyright message. term_writes("(c)"); diff --git a/makefile b/makefile index a8da3dc..946f2e4 100755 --- a/makefile +++ b/makefile @@ -33,6 +33,7 @@ kernel/utils.o \ kernel/serial.o \ kernel/gdt.o \ kernel/idt.o \ +kernel/isr.o \ kernel/kernel.o OBJS=\ @@ -64,6 +65,9 @@ $(ARCHDIR)/crtbegin.o $(ARCHDIR)/crtend.o: $(ARCHDIR)/gdt.o: nasm -f elf $(ARCHDIR)/gdt.s + +$(ARCHDIR)/isr.o: + nasm -f elf $(ARCHDIR)/isr.s .c.o: $(CC) -MD -c $< -o $@ -std=gnu11 $(CFLAGS) $(CPPFLAGS)