From 42fc169e10e518af7bdc3645db5d32f09a8ad070 Mon Sep 17 00:00:00 2001 From: xamidev Date: Mon, 22 Dec 2025 21:04:45 +0100 Subject: [PATCH] Interrupt Dispatch and Handling (for first common vectors) --- src/idt/idt.S | 2 ++ src/idt/idt.c | 3 ++- src/idt/idt.h | 3 +++ src/io/serial.c | 3 +++ src/kmain.c | 20 +++++++++++++++++--- src/mem/gdt.c | 3 +++ 6 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/idt/idt.S b/src/idt/idt.S index 60be323..7adf2bb 100644 --- a/src/idt/idt.S +++ b/src/idt/idt.S @@ -40,6 +40,7 @@ interrupt_stub: push rdx push rsi push rdi + push rsp push rbp push r8 push r9 @@ -65,6 +66,7 @@ interrupt_stub: pop r9 pop r8 pop rbp + pop rsp pop rdi pop rsi pop rdx diff --git a/src/idt/idt.c b/src/idt/idt.c index 21237b5..e13b7ab 100644 --- a/src/idt/idt.c +++ b/src/idt/idt.c @@ -44,13 +44,14 @@ void idt_init() // Each vector handler is 16-byte aligned, so *16 = address of that handler idt_set_entry(i, vector_0_handler + (i*16), 0); } + idt_load(&idt); + serial_kputs("kernel: idt: Initialized IDT!\n"); } struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context) { switch(context->vector_number) { - // TODO: add serial logs for all interrupts case 0: serial_kputs("kernel: idt: Divide Error!\n"); break; diff --git a/src/idt/idt.h b/src/idt/idt.h index 05ae631..37b6e32 100644 --- a/src/idt/idt.h +++ b/src/idt/idt.h @@ -3,6 +3,8 @@ #include +void idt_init(); + struct interrupt_descriptor { uint16_t address_low; @@ -34,6 +36,7 @@ struct cpu_status_t uint64_t r9; uint64_t r8; uint64_t rbp; + uint64_t rsp; uint64_t rdi; uint64_t rsi; uint64_t rdx; diff --git a/src/io/serial.c b/src/io/serial.c index 7584dfa..388b5b3 100644 --- a/src/io/serial.c +++ b/src/io/serial.c @@ -1,4 +1,5 @@ #include "../kernel.h" +#include "serial.h" void outb(int port, unsigned char data) { @@ -34,6 +35,8 @@ int serial_init() // Set normal operation mode outb(PORT + 4, 0x0F); + + serial_kputs("\n\nkernel: serial: Serial initialization OK!\n"); return 0; } diff --git a/src/kmain.c b/src/kmain.c index 7a65ab6..9616db4 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -6,6 +6,7 @@ #include "io/serial.h" #include "mem/gdt.h" #include "mem/utils.h" +#include "idt/idt.h" // Limine version used __attribute__((used, section(".limine_requests"))) @@ -35,6 +36,20 @@ static void hcf() } } +static inline void trigger_div0(void) +{ + asm volatile ( + "mov $1, %%rax\n" + "xor %%rdx, %%rdx\n" + "xor %%rcx, %%rcx\n" // divisor = 0 + "idiv %%rcx\n" + : + : + : "rax", "rcx", "rdx" + ); +} + + // This is our entry point void kmain() { @@ -47,14 +62,13 @@ void kmain() if (term_init()) hcf(); if (serial_init()) kputs("kernel: serial: error: Cannot init serial communication!"); - - serial_kputs("\n\nkernel: serial: Hello, world from serial!\n"); gdt_init(); - serial_kputs("kernel: gdt: Initialized GDT!"); + idt_init(); // Draw something printf("%s, %s!", "Hello", "world"); + trigger_div0(); hcf(); } diff --git a/src/mem/gdt.c b/src/mem/gdt.c index 133973e..fb82ae7 100644 --- a/src/mem/gdt.c +++ b/src/mem/gdt.c @@ -1,5 +1,6 @@ #include "gdt.h" #include +#include "../io/serial.h" // Descriptors are 8-byte wide (64bits) // So the selectors will be (in bytes): 0x0, 0x8, 0x10, 0x18, etc.. @@ -76,4 +77,6 @@ void gdt_init() // Load the GDT we created, flush the old one gdt_load(); gdt_flush(); + + serial_kputs("kernel: gdt: Initialized GDT!\n"); } \ No newline at end of file