Interrupt Dispatch and Handling (for first common vectors)

This commit is contained in:
2025-12-22 21:04:45 +01:00
parent d0b4da0596
commit 42fc169e10
6 changed files with 30 additions and 4 deletions

View File

@@ -40,6 +40,7 @@ interrupt_stub:
push rdx push rdx
push rsi push rsi
push rdi push rdi
push rsp
push rbp push rbp
push r8 push r8
push r9 push r9
@@ -65,6 +66,7 @@ interrupt_stub:
pop r9 pop r9
pop r8 pop r8
pop rbp pop rbp
pop rsp
pop rdi pop rdi
pop rsi pop rsi
pop rdx pop rdx

View File

@@ -44,13 +44,14 @@ void idt_init()
// Each vector handler is 16-byte aligned, so <vector_no>*16 = address of that handler // Each vector handler is 16-byte aligned, so <vector_no>*16 = address of that handler
idt_set_entry(i, vector_0_handler + (i*16), 0); 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) struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
{ {
switch(context->vector_number) switch(context->vector_number)
{ {
// TODO: add serial logs for all interrupts
case 0: case 0:
serial_kputs("kernel: idt: Divide Error!\n"); serial_kputs("kernel: idt: Divide Error!\n");
break; break;

View File

@@ -3,6 +3,8 @@
#include <stdint.h> #include <stdint.h>
void idt_init();
struct interrupt_descriptor struct interrupt_descriptor
{ {
uint16_t address_low; uint16_t address_low;
@@ -34,6 +36,7 @@ struct cpu_status_t
uint64_t r9; uint64_t r9;
uint64_t r8; uint64_t r8;
uint64_t rbp; uint64_t rbp;
uint64_t rsp;
uint64_t rdi; uint64_t rdi;
uint64_t rsi; uint64_t rsi;
uint64_t rdx; uint64_t rdx;

View File

@@ -1,4 +1,5 @@
#include "../kernel.h" #include "../kernel.h"
#include "serial.h"
void outb(int port, unsigned char data) void outb(int port, unsigned char data)
{ {
@@ -34,6 +35,8 @@ int serial_init()
// Set normal operation mode // Set normal operation mode
outb(PORT + 4, 0x0F); outb(PORT + 4, 0x0F);
serial_kputs("\n\nkernel: serial: Serial initialization OK!\n");
return 0; return 0;
} }

View File

@@ -6,6 +6,7 @@
#include "io/serial.h" #include "io/serial.h"
#include "mem/gdt.h" #include "mem/gdt.h"
#include "mem/utils.h" #include "mem/utils.h"
#include "idt/idt.h"
// Limine version used // Limine version used
__attribute__((used, section(".limine_requests"))) __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 // This is our entry point
void kmain() void kmain()
{ {
@@ -47,14 +62,13 @@ void kmain()
if (term_init()) hcf(); if (term_init()) hcf();
if (serial_init()) kputs("kernel: serial: error: Cannot init serial communication!"); if (serial_init()) kputs("kernel: serial: error: Cannot init serial communication!");
serial_kputs("\n\nkernel: serial: Hello, world from serial!\n");
gdt_init(); gdt_init();
serial_kputs("kernel: gdt: Initialized GDT!"); idt_init();
// Draw something // Draw something
printf("%s, %s!", "Hello", "world"); printf("%s, %s!", "Hello", "world");
trigger_div0();
hcf(); hcf();
} }

View File

@@ -1,5 +1,6 @@
#include "gdt.h" #include "gdt.h"
#include <stdint.h> #include <stdint.h>
#include "../io/serial.h"
// Descriptors are 8-byte wide (64bits) // Descriptors are 8-byte wide (64bits)
// So the selectors will be (in bytes): 0x0, 0x8, 0x10, 0x18, etc.. // 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 // Load the GDT we created, flush the old one
gdt_load(); gdt_load();
gdt_flush(); gdt_flush();
serial_kputs("kernel: gdt: Initialized GDT!\n");
} }