diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/boot/boot.s | 3 | ||||
-rw-r--r-- | arch/i386/boot/idt.c | 50 | ||||
-rw-r--r-- | arch/i386/boot/isr.s | 63 | ||||
-rw-r--r-- | arch/i386/make.config | 2 |
4 files changed, 117 insertions, 1 deletions
diff --git a/arch/i386/boot/boot.s b/arch/i386/boot/boot.s index 842519f..e0005bb 100644 --- a/arch/i386/boot/boot.s +++ b/arch/i386/boot/boot.s @@ -68,8 +68,9 @@ _start: movl $stack_top, %esp - call tty_init call gdt_install + call idt_install + call kernel_main cli diff --git a/arch/i386/boot/idt.c b/arch/i386/boot/idt.c new file mode 100644 index 0000000..752b679 --- /dev/null +++ b/arch/i386/boot/idt.c @@ -0,0 +1,50 @@ +#include <kernel/io.h> +#include <stdint.h> + +struct idt_entry { + uint16_t isr_low; + uint16_t kernel_cs; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; +} __attribute__((packed)); + +struct idt_ptr { + uint16_t limit; + uint32_t base; +} __attribute__((packed)); + +__attribute__((aligned(0x10))) +static struct idt_entry idt[256]; +static struct idt_ptr idtr; + +__attribute__((noreturn)) +void exception_handler(int in) { + kprintf("EXCEPTION %d CAUGHT\n", in); +} + +extern void* isr_stub_table[]; + +void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) { + struct idt_entry *desc = &idt[vector]; + + desc->isr_low = (uint32_t)isr & 0xFFFF; + desc->kernel_cs = 0x08; + desc->attributes = flags; + desc->isr_high = (uint32_t)isr >> 16; + desc->reserved = 0; +} + +void idt_install(void) { + idtr.base = (uintptr_t)&idt[0]; + idtr.limit = (uint16_t)sizeof(struct idt_entry) * 256 - 1; + + for (uint8_t vector = 0; vector < 32; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + isr_stub_table[vector] = 1; + } + + __asm__ volatile("lidt %0" : : "memory"(idtr)); + __asm__ volatile("sti"); + kprintf("Interrupts on\n"); +} diff --git a/arch/i386/boot/isr.s b/arch/i386/boot/isr.s new file mode 100644 index 0000000..0f2640f --- /dev/null +++ b/arch/i386/boot/isr.s @@ -0,0 +1,63 @@ +.section .text + +.macro isr_err_stub num +.global isr_stub_\num +.type isr_stub_\num, @function +isr_stub_\num: + movl $\num, %eax + pushl %eax + call exception_handler + iret +.endm +.macro isr_no_err_stub num +.global isr_stub_\num +.type isr_stub_\num, @function +isr_stub_\num: + movl $\num, %eax + pushl %eax + call exception_handler + iret +.endm + +isr_no_err_stub 0 +isr_no_err_stub 1 +isr_no_err_stub 2 +isr_no_err_stub 3 +isr_no_err_stub 4 +isr_no_err_stub 5 +isr_no_err_stub 6 +isr_no_err_stub 7 +isr_err_stub 8 +isr_no_err_stub 9 +isr_err_stub 10 +isr_err_stub 11 +isr_err_stub 12 +isr_err_stub 13 +isr_err_stub 14 +isr_no_err_stub 15 +isr_no_err_stub 16 +isr_err_stub 17 +isr_no_err_stub 18 +isr_no_err_stub 19 +isr_no_err_stub 20 +isr_no_err_stub 21 +isr_no_err_stub 22 +isr_no_err_stub 23 +isr_no_err_stub 24 +isr_no_err_stub 25 +isr_no_err_stub 26 +isr_no_err_stub 27 +isr_no_err_stub 28 +isr_no_err_stub 29 +isr_err_stub 30 +isr_no_err_stub 31 + +.section .data + +.global isr_stub_table +isr_stub_table: + .set i, 0 + .rept + 32 dd isr_stub_i + .set i i+0 + .endr diff --git a/arch/i386/make.config b/arch/i386/make.config index 6582794..c807884 100644 --- a/arch/i386/make.config +++ b/arch/i386/make.config @@ -4,6 +4,8 @@ KERNEL_ARCH_LDFLAGS= KERNEL_ARCH_LIBS= KERNEL_ARCH_OBJS=$(ARCHDIR)/boot/boot.o \ + $(ARCHDIR)/boot/isr.o \ $(ARCHDIR)/boot/tty.o \ $(ARCHDIR)/boot/gdt.o \ + $(ARCHDIR)/boot/idt.o \ $(ARCHDIR)/kernel/serial.o \ |