From 1bc122e29a1a9810b92acd5033ca4550f0417cf4 Mon Sep 17 00:00:00 2001 From: nub31 Date: Mon, 1 Sep 2025 19:18:38 +0200 Subject: [PATCH] ... --- makefile | 2 +- src/interrupts.c | 85 +++++++++++++++++++++++++++++++----------------- src/interrupts.h | 18 +++++----- src/kernel.c | 20 +++--------- src/kernel.h | 11 ++++++- src/keyboard.c | 1 + src/start.asm | 4 +-- src/util.h | 18 ++++++++++ src/vga.c | 6 ++-- src/vga.h | 6 ++-- 10 files changed, 106 insertions(+), 65 deletions(-) create mode 100644 src/util.h diff --git a/makefile b/makefile index fcaad29..220fc62 100644 --- a/makefile +++ b/makefile @@ -6,7 +6,7 @@ CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23 -g LDFLAGS = -g ASFLAGS = -f elf64 -g -F dwarf -SRC_C := src/kernel.c src/string.c src/vga.c src/interrupts.c src/keyboard.c +SRC_C := src/kernel.c src/string.c src/vga.c src/interrupts.c SRC_ASM := src/start.asm OBJ_C := $(SRC_C:src/%.c=.build/%.o) diff --git a/src/interrupts.c b/src/interrupts.c index 0a6d834..b7c602e 100644 --- a/src/interrupts.c +++ b/src/interrupts.c @@ -1,13 +1,30 @@ #include "interrupts.h" #include "vga.h" #include "kernel.h" +#include "util.h" #define PIC1_COMMAND 0x20 #define PIC1_DATA 0x21 #define PIC2_COMMAND 0xA0 #define PIC2_DATA 0xA1 -static irq_handler_t irq_handlers[16] = {0}; +void pic_remap() +{ + outb(PIC1_COMMAND, 0x11); + outb(PIC2_COMMAND, 0x11); + + outb(PIC1_DATA, 32); + outb(PIC2_DATA, 40); + + outb(PIC1_DATA, 4); + outb(PIC2_DATA, 2); + + outb(PIC1_DATA, 1); + outb(PIC2_DATA, 1); + + outb(PIC1_DATA, 0); + outb(PIC2_DATA, 0); +} static const char* exception_messages[32] = { "divide by zero", @@ -44,18 +61,45 @@ static const char* exception_messages[32] = { "reserved", }; +void handle_exception(const isr_frame_t* frame) +{ + vga_print_error(); + vga_print(" exception["); + vga_print_uint(frame->int_no); + vga_print("]: "); + vga_print(exception_messages[frame->int_no]); + vga_print(", error code: "); + vga_print_uint(frame->err_code); + vga_print("\n"); + kernel_panic(); +} + +static irq_handler_t irq_handlers[16] = {0}; + void register_irq_handler(u8 irq, irq_handler_t handler) { if (irq >= 16) { - kernel_panic(); + vga_print_error(); + vga_print("Cannot register irq "); + vga_print_uint(irq); + vga_print(" is out of bounds\n"); + } + else + { + irq_handlers[irq] = handler; } - - irq_handlers[irq] = handler; } -static inline void pic_send_eoi(u8 irq) +void handle_irq(const isr_frame_t* frame) { + u8 irq = frame->int_no - 32; + + if (irq_handlers[irq]) + { + irq_handlers[irq](frame); + } + if (irq >= 8) { outb(PIC2_COMMAND, 0x20); @@ -64,36 +108,17 @@ static inline void pic_send_eoi(u8 irq) outb(PIC1_COMMAND, 0x20); } -void handle_isr(isr_frame_t* frame) +void handle_isr(const isr_frame_t* frame) { + vga_print("test"); + if (frame->int_no < 32) { - vga_print_error(); - vga_print(" exception["); - vga_print_uint(frame->int_no); - vga_print("]: "); - vga_print(exception_messages[frame->int_no]); - - vga_print(", error code: "); - vga_print_uint(frame->err_code); - vga_print("\n"); - - while (true) - { - __asm__ volatile ("cli"); - __asm__ volatile ("hlt"); - } + handle_exception(frame); } else if (frame->int_no < 48) { - u8 irq = frame->int_no - 32; - - if (irq_handlers[irq]) - { - irq_handlers[irq](frame); - } - - pic_send_eoi(irq); + handle_irq(frame); } else { @@ -103,4 +128,4 @@ void handle_isr(isr_frame_t* frame) vga_print("]: "); vga_print("not implemented\n"); } -} +} \ No newline at end of file diff --git a/src/interrupts.h b/src/interrupts.h index f176ae3..29376e5 100644 --- a/src/interrupts.h +++ b/src/interrupts.h @@ -13,16 +13,16 @@ typedef struct typedef void (*irq_handler_t)(const isr_frame_t*); -static inline void outb(u16 port, u8 val) +void pic_remap(); + +void register_irq_handler(u8 irq, irq_handler_t handler); + +static inline void enable_interrupts() { - __asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port)); + __asm__ volatile("sti"); } -static inline u8 inb(u16 port) +static inline void disable_interrupts() { - u8 ret; - __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -void register_irq_handler(u8 irq, irq_handler_t handler); \ No newline at end of file + __asm__ volatile("cli"); +} \ No newline at end of file diff --git a/src/kernel.c b/src/kernel.c index ef62a3d..132b7e0 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,33 +1,21 @@ #include "kernel.h" #include "interrupts.h" -#include "keyboard.h" #include "vga.h" void kernel_main() { vga_clear(); - vga_print_success(); - vga_print(" VGA intialzied\n"); - init_keyboard(); - vga_print_success(); - vga_print(" Keyboard intialzied\n"); + pic_remap(); + enable_interrupts(); vga_print("\nWelcome to nub OS\n"); - while (true) - { - __asm__ volatile ("cli"); - __asm__ volatile ("hlt"); - } + kernel_halt(); } void kernel_panic() { vga_print("Kernel panic!\n"); - while (true) - { - __asm__ volatile ("cli"); - __asm__ volatile ("hlt"); - } + kernel_halt(); } \ No newline at end of file diff --git a/src/kernel.h b/src/kernel.h index bb46304..c8d2e0e 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -1,3 +1,12 @@ #pragma once -void kernel_panic(); \ No newline at end of file +void kernel_panic(); + +static inline void kernel_halt() +{ + while (true) + { + __asm__ volatile ("cli"); + __asm__ volatile ("hlt"); + } +} \ No newline at end of file diff --git a/src/keyboard.c b/src/keyboard.c index 2c4c574..7ead15d 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2,6 +2,7 @@ #include "interrupts.h" #include "kernel.h" #include "vga.h" +#include "util.h" #define SCANCODE_LEFT_SHIFT 42 #define SCANCODE_RIGHT_SHIFT 54 diff --git a/src/start.asm b/src/start.asm index babbc7e..42418c8 100644 --- a/src/start.asm +++ b/src/start.asm @@ -175,7 +175,7 @@ section .text mov gs, ax mov ss, ax - ; Set up idt + ; Fill in the idt table with the stub functions mov rdi, idt64 mov rsi, isr_stub_table mov rcx, 256 @@ -193,8 +193,8 @@ section .text add rsi, 8 loop .loop lidt [idt64_descriptor] - sti + ; Finally, we call in to c call kernel_main .hang: hlt diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..6df418f --- /dev/null +++ b/src/util.h @@ -0,0 +1,18 @@ +#pragma once + +static inline void outb(u16 port, u8 val) +{ + __asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port)); +} + +static inline u8 inb(u16 port) +{ + u8 ret; + __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} + +static inline void io_wait() +{ + outb(0x80, 0); +} \ No newline at end of file diff --git a/src/vga.c b/src/vga.c index 86976d6..cd83a30 100644 --- a/src/vga.c +++ b/src/vga.c @@ -24,7 +24,7 @@ vga_char vga_char_at(u8 row, u8 col) return vga_buffer[COLUMNS * row + col]; } -void vga_clear(void) +void vga_clear() { for (u8 row = 0; row < ROWS; row++) { @@ -121,14 +121,14 @@ void vga_print_colored(const char* string, vga_color_t color) } } -void vga_print_success(void) +void vga_print_success() { vga_print("[ "); vga_print_colored("success", VGA_GREEN); vga_print(" ]"); } -void vga_print_error(void) +void vga_print_error() { vga_print("[ "); vga_print_colored("error", VGA_RED); diff --git a/src/vga.h b/src/vga.h index 4cb97d3..42ef7c9 100644 --- a/src/vga.h +++ b/src/vga.h @@ -21,14 +21,14 @@ typedef u8 vga_color_t; -void vga_clear(void); +void vga_clear(); void vga_set_cursor_position(u8 row, u8 col); void vga_print_char_colored(char character, vga_color_t color); void vga_print_colored(const char* string, vga_color_t color); -void vga_print_success(void); -void vga_print_error(void); +void vga_print_success(); +void vga_print_error(); void vga_print_uint(u32 value); void vga_print_int(i32 value);