diff --git a/src/arch/arch.h b/src/arch/arch.h index b144135..faca849 100644 --- a/src/arch/arch.h +++ b/src/arch/arch.h @@ -14,16 +14,23 @@ typedef struct size_t num_regions; } memory_map_t; -extern memory_map_t memory_map; +typedef void (*arch_panic_t)(const char*); +typedef void (*arch_putchar_t)(char c); +typedef uint64_t (*arch_page_size_t)(); +typedef void (*arch_enable_interrupts_t)(); +typedef void (*arch_disable_interrupts_t)(); +typedef memory_map_t (*arch_get_memory_map_t)(); +typedef void (*arch_halt_t)(); -void arch_panic(const char* msg); -void arch_putchar(char c); +typedef struct +{ + arch_panic_t panic; + arch_putchar_t putchar; + arch_page_size_t page_size; + arch_enable_interrupts_t enable_interrupts; + arch_disable_interrupts_t disable_interrupts; + arch_get_memory_map_t get_memory_map; + arch_halt_t halt; +} arch_api_t; -uintptr_t arch_page_size(); - -void arch_interrupts_enable(); -void arch_interrupts_disable(); - -void arch_register_interrupt_handler(int vector, void (*handler)(void)); - -void arch_halt(); \ No newline at end of file +extern arch_api_t arch_api; \ No newline at end of file diff --git a/src/arch/x86_64/arch.c b/src/arch/x86_64/arch.c deleted file mode 100644 index 217714a..0000000 --- a/src/arch/x86_64/arch.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "arch.h" -#include "console/console.h" -#include "interrupts/idt.h" -#include "interrupts/irq.h" -#include "interrupts/isr.h" -#include "kernel.h" -#include "memory/mmap.h" -#include "multiboot.h" -#include "x86_64/util.h" - -void x86_64_main(uint32_t magic, multiboot_info_t* info) -{ - console_clear(); - - if (magic != 0x2BADB002) - { - arch_panic("Multiboot magic does not match\n"); - } - - if (info == NULL) - { - arch_panic("Multiboot info is NULL\n"); - } - - idt_init(); - remap_pic(); - map_memory(info); - enable_interrupts(); - kernel_main(); -} - -void arch_panic(const char* msg) -{ - printf(msg); - arch_halt(); -} - -void arch_putchar(char c) -{ - console_put_char(c, VGA_DEFAULT_COLOR); -} - -uintptr_t arch_page_size() -{ - return 4096; -} - -void arch_interrupts_enable() -{ - enable_interrupts(); -} - -void arch_interrupts_disable() -{ - disable_interrupts(); -} - -void arch_register_interrupt_handler(int vector, void (*handler)(void)) -{ - register_irq_handler(vector, (irq_handler_t)handler); -} - -void arch_halt() -{ - halt(); -} \ No newline at end of file diff --git a/src/arch/x86_64/interrupts/exceptions.c b/src/arch/x86_64/interrupts/exceptions.c index 4493d59..bf2fee6 100644 --- a/src/arch/x86_64/interrupts/exceptions.c +++ b/src/arch/x86_64/interrupts/exceptions.c @@ -1,5 +1,5 @@ #include "exceptions.h" -#include "arch.h" +#include "../panic.h" static const char* exception_messages[32] = { "divide by zero", @@ -39,5 +39,5 @@ static const char* exception_messages[32] = { void handle_exception(const isr_frame_t* frame) { printf("exception[%d]: %s, error code: %d\n", frame->int_no, exception_messages[frame->int_no], frame->err_code); - arch_panic("An unhandled exception occurred"); + panic("An unhandled exception occurred"); } \ No newline at end of file diff --git a/src/arch/x86_64/interrupts/isr.h b/src/arch/x86_64/interrupts/isr.h index 065b7d3..77e11e1 100644 --- a/src/arch/x86_64/interrupts/isr.h +++ b/src/arch/x86_64/interrupts/isr.h @@ -9,14 +9,4 @@ typedef struct uint64_t int_no; uint64_t err_code; uint64_t rip, cs, rflags, rsp, ss; -} __attribute__((packed)) isr_frame_t; - -static inline void enable_interrupts() -{ - __asm__ volatile("sti"); -} - -static inline void disable_interrupts() -{ - __asm__ volatile("cli"); -} \ No newline at end of file +} __attribute__((packed)) isr_frame_t; \ No newline at end of file diff --git a/src/arch/x86_64/main.c b/src/arch/x86_64/main.c new file mode 100644 index 0000000..2f49e06 --- /dev/null +++ b/src/arch/x86_64/main.c @@ -0,0 +1,48 @@ +#include "console/console.h" +#include "interrupts/idt.h" +#include "interrupts/irq.h" +#include "kernel.h" +#include "memory/mmap.h" +#include "panic.h" +#include "util.h" + +void x86_64_main(uint32_t magic, multiboot_info_t* info) +{ + console_clear(); + + if (magic != 0x2BADB002) + { + panic("Multiboot magic does not match\n"); + } + + if (info == NULL) + { + panic("Multiboot info is NULL\n"); + } + + idt_init(); + remap_pic(); + map_memory(info); + enable_interrupts(); + kernel_main(); +} + +void arch_console_putchar(char c) +{ + console_put_char(c, VGA_DEFAULT_COLOR); +} + +uint64_t arch_page_size() +{ + return 4096; +} + +arch_api_t arch_api = { + .panic = panic, + .putchar = arch_console_putchar, + .page_size = arch_page_size, + .enable_interrupts = enable_interrupts, + .disable_interrupts = disable_interrupts, + .get_memory_map = get_memory_map, + .halt = halt, +}; \ No newline at end of file diff --git a/src/arch/x86_64/memory/mmap.c b/src/arch/x86_64/memory/mmap.c index 4907179..71d9809 100644 --- a/src/arch/x86_64/memory/mmap.c +++ b/src/arch/x86_64/memory/mmap.c @@ -1,20 +1,18 @@ #include "mmap.h" +#include "../panic.h" #define USABLE_REGION_SIZE 32 -memory_map_t memory_map; - static memory_region_t usable_regions[USABLE_REGION_SIZE]; +static size_t num_regions = 0; void map_memory(multiboot_info_t* info) { if (!(info->flags & (1 << 6))) { - arch_panic("Invalid memory map given by bootloader\n"); + panic("Invalid memory map given by bootloader\n"); } - size_t num_regions = 0; - uint64_t offset = 0; while (offset < info->mmap_length) { @@ -40,8 +38,11 @@ void map_memory(multiboot_info_t* info) offset += mmmt->size + sizeof(mmmt->size); } +} - memory_map = (memory_map_t){ +memory_map_t get_memory_map() +{ + return (memory_map_t){ .num_regions = num_regions, .regions = usable_regions, }; diff --git a/src/arch/x86_64/memory/mmap.h b/src/arch/x86_64/memory/mmap.h index d93fb3b..54a84a7 100644 --- a/src/arch/x86_64/memory/mmap.h +++ b/src/arch/x86_64/memory/mmap.h @@ -4,3 +4,4 @@ #include "arch.h" void map_memory(multiboot_info_t* mbd); +memory_map_t get_memory_map(); \ No newline at end of file diff --git a/src/arch/x86_64/panic.c b/src/arch/x86_64/panic.c new file mode 100644 index 0000000..7b51d5e --- /dev/null +++ b/src/arch/x86_64/panic.c @@ -0,0 +1,7 @@ +#include "util.h" + +void panic(const char* msg) +{ + printf(msg); + halt(); +} \ No newline at end of file diff --git a/src/arch/x86_64/panic.h b/src/arch/x86_64/panic.h new file mode 100644 index 0000000..e9e18af --- /dev/null +++ b/src/arch/x86_64/panic.h @@ -0,0 +1,3 @@ +#pragma once + +void panic(const char* msg); \ No newline at end of file diff --git a/src/arch/x86_64/util.h b/src/arch/x86_64/util.h index 858954e..8db584c 100644 --- a/src/arch/x86_64/util.h +++ b/src/arch/x86_64/util.h @@ -110,4 +110,14 @@ static inline void halt() { __asm__ volatile("hlt"); } +} + +static inline void enable_interrupts() +{ + __asm__ volatile("sti"); +} + +static inline void disable_interrupts() +{ + __asm__ volatile("cli"); } \ No newline at end of file diff --git a/src/kernel/pmm.c b/src/kernel/pmm.c index 4cb2aed..135476a 100644 --- a/src/kernel/pmm.c +++ b/src/kernel/pmm.c @@ -10,14 +10,16 @@ static uint64_t free_pages = 0; void pmm_init() { + memory_map_t memory_map = arch_api.get_memory_map(); + memset(page_bitmap, 0xFF, BITMAP_SIZE); for (size_t i = 0; i < memory_map.num_regions; i++) { memory_region_t region = memory_map.regions[i]; - uint64_t start_page = region.base_address / arch_page_size(); - uint64_t num_pages = region.length / arch_page_size(); + uint64_t start_page = region.base_address / arch_api.page_size(); + uint64_t num_pages = region.length / arch_api.page_size(); for (uint64_t page = start_page; page < start_page + num_pages; page++) { @@ -36,7 +38,7 @@ void pmm_init() } // Reserve first 64MB which is reserved by boot code - for (uint64_t page = 0; page < (64 * 1024 * 1024) / arch_page_size(); page++) + for (uint64_t page = 0; page < (64 * 1024 * 1024) / arch_api.page_size(); page++) { if (page < BITMAP_SIZE * 8) { @@ -62,7 +64,7 @@ uint64_t pmm_alloc_page() { page_bitmap[i] |= (1 << bit); free_pages--; - return ((i * 8 + bit) * arch_page_size()); + return ((i * 8 + bit) * arch_api.page_size()); } } } @@ -74,7 +76,7 @@ uint64_t pmm_alloc_page() // Frees the physical page at the specified address void pmm_free_page(uint64_t addr) { - uint64_t page = addr / arch_page_size(); + uint64_t page = addr / arch_api.page_size(); if (page < BITMAP_SIZE * 8) { if (page_bitmap[page / 8] & (1 << (page % 8))) diff --git a/src/stdlib/io.c b/src/stdlib/io.c index 37f2c1a..63d606f 100644 --- a/src/stdlib/io.c +++ b/src/stdlib/io.c @@ -15,20 +15,20 @@ void printf(const char* fmt, ...) if (fmt[i] == '%') { - arch_putchar('%'); + arch_api.putchar('%'); } else if (fmt[i] == 's') { const char* str = va_arg(args, const char*); for (size_t j = 0; str[j] != '\0'; j++) { - arch_putchar(str[j]); + arch_api.putchar(str[j]); } } else if (fmt[i] == 'c') { char character = (char)va_arg(args, int64_t); - arch_putchar(character); + arch_api.putchar(character); } else if (fmt[i] == 'd') { @@ -37,7 +37,7 @@ void printf(const char* fmt, ...) itoa64(val, buf); for (size_t j = 0; buf[j] != '\0'; j++) { - arch_putchar(buf[j]); + arch_api.putchar(buf[j]); } } else if (fmt[i] == 'u') @@ -47,7 +47,7 @@ void printf(const char* fmt, ...) uitoa64(val, buf); for (size_t j = 0; buf[j] != '\0'; j++) { - arch_putchar(buf[j]); + arch_api.putchar(buf[j]); } } else if (fmt[i] == 'x') @@ -57,12 +57,12 @@ void printf(const char* fmt, ...) uitoa64_hex(val, buf); for (size_t j = 0; buf[j] != '\0'; j++) { - arch_putchar(buf[j]); + arch_api.putchar(buf[j]); } } else { - arch_putchar(fmt[i]); + arch_api.putchar(fmt[i]); } } else if (fmt[i] == '%') @@ -71,7 +71,7 @@ void printf(const char* fmt, ...) } else { - arch_putchar(fmt[i]); + arch_api.putchar(fmt[i]); } }