diff --git a/bin/boot.bin b/bin/boot.bin index 1a008f3..9a84534 100644 Binary files a/bin/boot.bin and b/bin/boot.bin differ diff --git a/bin/kernel.bin b/bin/kernel.bin index c74729f..746678e 100755 Binary files a/bin/kernel.bin and b/bin/kernel.bin differ diff --git a/obj/kernel/kernel.o b/obj/kernel/kernel.o index 101664c..987d3fc 100644 Binary files a/obj/kernel/kernel.o and b/obj/kernel/kernel.o differ diff --git a/obj/kernel/platform/interrupts/idt.o b/obj/kernel/platform/interrupts/idt.o deleted file mode 100644 index 19c1646..0000000 Binary files a/obj/kernel/platform/interrupts/idt.o and /dev/null differ diff --git a/obj/kernel/platform/interrupts/int.o b/obj/kernel/platform/interrupts/int.o index 83d980d..14dbc95 100644 Binary files a/obj/kernel/platform/interrupts/int.o and b/obj/kernel/platform/interrupts/int.o differ diff --git a/obj/kernel/platform/interrupts/int_lowlevel.o b/obj/kernel/platform/interrupts/int_lowlevel.o new file mode 100644 index 0000000..98f9819 Binary files /dev/null and b/obj/kernel/platform/interrupts/int_lowlevel.o differ diff --git a/obj/kernel/platform/interrupts/isr.o b/obj/kernel/platform/interrupts/isr.o deleted file mode 100644 index 925c526..0000000 Binary files a/obj/kernel/platform/interrupts/isr.o and /dev/null differ diff --git a/os-image.bin b/os-image.bin index 218db70..5d875f0 100644 Binary files a/os-image.bin and b/os-image.bin differ diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 1317644..a3f295a 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,8 +1,7 @@ #include "./platform/drivers/ports.h" #include "print.h" #include "./platform/types.h" -#include "./platform/interrupts/idt.h" -#include "./platform/interrupts/isr.h" +#include "./platform/interrupts/int.h" void dummy_test_entrypoint() {} @@ -48,4 +47,8 @@ void main() { print_str("This program is provided \"as-is\" and no express or implied warranty is provided.\n"); print_str("The full license can be found at /sys/LICENCE on this system or ./LICENCE in the source tree.\n"); + idt_init(); + kernel_msg_ok("Interrupts initialized"); + + __asm__ __volatile__("int $2"); } \ No newline at end of file diff --git a/src/kernel/platform/interrupts/int.c b/src/kernel/platform/interrupts/int.c new file mode 100644 index 0000000..3e63985 --- /dev/null +++ b/src/kernel/platform/interrupts/int.c @@ -0,0 +1,29 @@ +#include "int.h" +#include "../../print.h" + +void exception_handler() { + print_str("I"); +} + +void idt_set_descriptor(u8 vector, void* isr, u8 flags) { + idt_entry_t* descriptor = &idt[vector]; + + descriptor->isr_low = (u32)isr & 0xFFFF; + descriptor->kernel_cs = 0x08; // this value can be whatever offset your kernel code selector is in your GDT + descriptor->attributes = flags; + descriptor->isr_high = (u32)isr >> 16; + descriptor->reserved = 0; +} + +void idt_init() { + idtr.base = (u32)&idt[0]; + idtr.limit = (u16)sizeof(idt_entry_t) * 256 - 1; + + for (u8 vector = 0; vector < 32; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + isr_stub_table[vector] = TRUE; + } + + __asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT + __asm__ volatile ("sti"); // set the interrupt flag +} \ No newline at end of file diff --git a/src/kernel/platform/interrupts/int.h b/src/kernel/platform/interrupts/int.h new file mode 100644 index 0000000..a58b890 --- /dev/null +++ b/src/kernel/platform/interrupts/int.h @@ -0,0 +1,33 @@ +#ifndef INT_H +#define INT_H + +#include "../types.h" + +typedef struct { + u16 isr_low; // The lower 16 bits of the ISR's address + u16 kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR + u8 reserved; // Set to zero + u8 attributes; // Type and attributes; see the IDT page + u16 isr_high; // The higher 16 bits of the ISR's address +} __attribute__((packed)) idt_entry_t; + +__attribute__((aligned(0x10))) +static idt_entry_t idt[256]; // Create an array of IDT entries; aligned for performance + +typedef struct { + u16 limit; + u32 base; +} __attribute__((packed)) idtr_t; + +static idtr_t idtr; + +__attribute__((noreturn)) +void exception_handler(void); + +void idt_set_descriptor(u8 vector, void* isr, u8 flags); + +extern void* isr_stub_table[]; + +void idt_init(void); + +#endif \ No newline at end of file diff --git a/src/kernel/platform/interrupts/int_lowlevel.asm b/src/kernel/platform/interrupts/int_lowlevel.asm new file mode 100644 index 0000000..a38fd41 --- /dev/null +++ b/src/kernel/platform/interrupts/int_lowlevel.asm @@ -0,0 +1,54 @@ +%macro isr_err_stub 1 +isr_stub_%+%1: + call exception_handler + iret +%endmacro +; if writing for 64-bit, use iretq instead +%macro isr_no_err_stub 1 +isr_stub_%+%1: + call exception_handler + iret +%endmacro + +extern exception_handler +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 + +global isr_stub_table +isr_stub_table: +%assign i 0 +%rep 32 + dd isr_stub_%+i ; use DQ instead if targeting 64-bit +%assign i i+1 +%endrep +