From 0f6b66a4869552ce74344366e9c2c80e1cbf3acc Mon Sep 17 00:00:00 2001 From: nub31 Date: Fri, 5 Sep 2025 21:41:00 +0200 Subject: [PATCH] ... --- src/arch/arch.h | 16 ---- src/arch/x86_64/console/console.c | 12 +-- src/arch/x86_64/console/console.h | 2 +- src/arch/x86_64/interrupts/irq.c | 4 +- src/arch/x86_64/interrupts/irq.h | 2 +- src/arch/x86_64/interrupts/isr.h | 10 +-- src/arch/x86_64/main.c | 23 ++--- src/arch/x86_64/mem.c | 134 ++++++++++++++++++++++++++++++ src/arch/x86_64/mem.h | 9 ++ src/arch/x86_64/memory/mmap.c | 49 ----------- src/arch/x86_64/memory/mmap.h | 7 -- src/arch/x86_64/util.h | 20 ++--- src/kernel/kernel.c | 6 +- src/kernel/pmm.c | 88 -------------------- src/kernel/pmm.h | 7 -- src/stdlib/def.h | 27 ++---- src/stdlib/io.c | 8 +- src/stdlib/mem.c | 12 ++- src/stdlib/mem.h | 3 +- src/stdlib/string.c | 8 +- src/stdlib/string.h | 8 +- 21 files changed, 210 insertions(+), 245 deletions(-) create mode 100644 src/arch/x86_64/mem.c create mode 100644 src/arch/x86_64/mem.h delete mode 100644 src/arch/x86_64/memory/mmap.c delete mode 100644 src/arch/x86_64/memory/mmap.h delete mode 100644 src/kernel/pmm.c delete mode 100644 src/kernel/pmm.h diff --git a/src/arch/arch.h b/src/arch/arch.h index faca849..393df9c 100644 --- a/src/arch/arch.h +++ b/src/arch/arch.h @@ -2,34 +2,18 @@ #include "std.h" -typedef struct -{ - uint64_t base_address; - size_t length; -} memory_region_t; - -typedef struct -{ - memory_region_t* regions; - size_t num_regions; -} memory_map_t; - 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)(); 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; diff --git a/src/arch/x86_64/console/console.c b/src/arch/x86_64/console/console.c index 39b0eb9..14665a4 100644 --- a/src/arch/x86_64/console/console.c +++ b/src/arch/x86_64/console/console.c @@ -5,15 +5,15 @@ typedef struct { - uint8_t character; - uint8_t color; + u8 character; + u8 color; } vga_char_t; static vga_char_t* vga_buffer = (vga_char_t*)0xb8000; -static uint8_t cursor_row = 0; -static uint8_t cursor_col = 0; +static u8 cursor_row = 0; +static u8 cursor_col = 0; -void console_put_char(char c, uint8_t color) +void console_put_char(char c, u8 color) { switch (c) { @@ -30,7 +30,7 @@ void console_put_char(char c, uint8_t color) } case '\t': { - uint8_t remainder = 4 - (cursor_col % 4); + u8 remainder = 4 - (cursor_col % 4); cursor_col += remainder; break; } diff --git a/src/arch/x86_64/console/console.h b/src/arch/x86_64/console/console.h index 0e72d9a..f53d9d2 100644 --- a/src/arch/x86_64/console/console.h +++ b/src/arch/x86_64/console/console.h @@ -21,5 +21,5 @@ #define VGA_DEFAULT_COLOR VGA_LIGHT_GRAY | VGA_BLACK << 4 -void console_put_char(char character, uint8_t color); +void console_put_char(char character, u8 color); void console_clear(); \ No newline at end of file diff --git a/src/arch/x86_64/interrupts/irq.c b/src/arch/x86_64/interrupts/irq.c index e587dfd..02a50c2 100644 --- a/src/arch/x86_64/interrupts/irq.c +++ b/src/arch/x86_64/interrupts/irq.c @@ -26,7 +26,7 @@ void remap_pic() outb(PIC2_DATA, 0); } -void register_irq_handler(uint8_t irq, irq_handler_t handler) +void register_irq_handler(u8 irq, irq_handler_t handler) { if (irq >= 16) { @@ -40,7 +40,7 @@ void register_irq_handler(uint8_t irq, irq_handler_t handler) void handle_irq(const isr_frame_t* frame) { - uint8_t irq = frame->int_no - 32; + u8 irq = frame->int_no - 32; if (irq_handlers[irq]) { diff --git a/src/arch/x86_64/interrupts/irq.h b/src/arch/x86_64/interrupts/irq.h index efecf72..8547507 100644 --- a/src/arch/x86_64/interrupts/irq.h +++ b/src/arch/x86_64/interrupts/irq.h @@ -6,4 +6,4 @@ typedef void (*irq_handler_t)(const isr_frame_t*); void remap_pic(); void handle_irq(const isr_frame_t* frame); -void register_irq_handler(uint8_t irq, irq_handler_t handler); \ No newline at end of file +void register_irq_handler(u8 irq, irq_handler_t handler); \ 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 77e11e1..e075bbd 100644 --- a/src/arch/x86_64/interrupts/isr.h +++ b/src/arch/x86_64/interrupts/isr.h @@ -4,9 +4,9 @@ typedef struct { - uint64_t r15, r14, r13, r12, r11, r10, r9, r8; - uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax; - uint64_t int_no; - uint64_t err_code; - uint64_t rip, cs, rflags, rsp, ss; + u64 r15, r14, r13, r12, r11, r10, r9, r8; + u64 rbp, rdi, rsi, rdx, rcx, rbx, rax; + u64 int_no; + u64 err_code; + u64 rip, cs, rflags, rsp, ss; } __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 index 2f49e06..245df90 100644 --- a/src/arch/x86_64/main.c +++ b/src/arch/x86_64/main.c @@ -1,12 +1,13 @@ +#include "arch.h" #include "console/console.h" #include "interrupts/idt.h" #include "interrupts/irq.h" #include "kernel.h" -#include "memory/mmap.h" +#include "mem.h" #include "panic.h" #include "util.h" -void x86_64_main(uint32_t magic, multiboot_info_t* info) +void x86_64_main(u32 magic, multiboot_info_t* info) { console_clear(); @@ -21,28 +22,20 @@ void x86_64_main(uint32_t magic, multiboot_info_t* info) } idt_init(); + + mem_init(info); + remap_pic(); - map_memory(info); enable_interrupts(); kernel_main(); } -void arch_console_putchar(char c) +void 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, + .putchar = console_putchar, .halt = halt, }; \ No newline at end of file diff --git a/src/arch/x86_64/mem.c b/src/arch/x86_64/mem.c new file mode 100644 index 0000000..3182336 --- /dev/null +++ b/src/arch/x86_64/mem.c @@ -0,0 +1,134 @@ +#include "mem.h" +#include "x86_64/panic.h" + +typedef struct +{ + u64 base_address; + size_t length; +} memory_region_t; + +typedef struct +{ + memory_region_t* regions; + size_t num_regions; +} memory_map_t; + +#define USABLE_REGION_SIZE 32 + +static memory_region_t usable_regions[USABLE_REGION_SIZE]; +static size_t num_regions = 0; + +#define BITMAP_SIZE 32768 // Supports up to 1GB of RAM +#define USABLE_REGION_SIZE 32 +#define PAGE_SIZE 4096 + +static u8 page_bitmap[BITMAP_SIZE]; +static u64 total_pages = 0; +static u64 free_pages = 0; + +void mem_init(multiboot_info_t* info) +{ + if (!(info->flags & (1 << 6))) + { + panic("Invalid memory map given by bootloader\n"); + } + + u64 offset = 0; + while (offset < info->mmap_length) + { + multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(info->mmap_addr + offset); + + if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE) + { + if (num_regions < USABLE_REGION_SIZE) + { + usable_regions[num_regions] = (memory_region_t){ + .base_address = mmmt->addr, + .length = mmmt->len, + }; + + num_regions++; + } + else + { + printf("System has more memory than the memory map can hold\n"); + break; + } + } + + offset += mmmt->size + sizeof(mmmt->size); + } + + memset(page_bitmap, 0xFF, BITMAP_SIZE); + + for (size_t i = 0; i < num_regions; i++) + { + memory_region_t region = usable_regions[i]; + + u64 start_page = region.base_address / PAGE_SIZE; + u64 num_pages = region.length / PAGE_SIZE; + + for (u64 page = start_page; page < start_page + num_pages; page++) + { + if (page < BITMAP_SIZE * 8) + { + page_bitmap[page / 8] &= ~(1 << (page % 8)); + free_pages++; + total_pages++; + } + else + { + printf("System has more ram than the bitmap allows!\n"); + break; + } + } + } + + // Reserve first 64MB which is reserved by boot code + // todo(nub31): Later we should only identity map only the kernel pages or make a higher half kernel + for (u64 page = 0; page < (64 * 1024 * 1024) / PAGE_SIZE; page++) + { + if (page < BITMAP_SIZE * 8) + { + if (!(page_bitmap[page / 8] & (1 << (page % 8)))) + { + page_bitmap[page / 8] |= (1 << (page % 8)); + free_pages--; + } + } + } +} + +u64 mem_alloc_physical_page() +{ + for (size_t i = 0; i < BITMAP_SIZE; i++) + { + if (page_bitmap[i] != 0xFF) + { + for (int bit = 0; bit < 8; bit++) + { + if (!(page_bitmap[i] & (1 << bit))) + { + page_bitmap[i] |= (1 << bit); + free_pages--; + return ((i * 8 + bit) * PAGE_SIZE); + } + } + } + } + + return 0; +} + +void mem_free_physical_page(u64 address) +{ + u64 page = address / PAGE_SIZE; + if (page < BITMAP_SIZE * 8) + { + if (page_bitmap[page / 8] & (1 << (page % 8))) + { + page_bitmap[page / 8] &= ~(1 << (page % 8)); + free_pages++; + } + } +} diff --git a/src/arch/x86_64/mem.h b/src/arch/x86_64/mem.h new file mode 100644 index 0000000..7f423d8 --- /dev/null +++ b/src/arch/x86_64/mem.h @@ -0,0 +1,9 @@ +#pragma once + +#include "std.h" +#include "x86_64/multiboot.h" + +void mem_init(multiboot_info_t* info); + +u64 mem_alloc_physical_page(); +void mem_free_physical_page(u64 address); \ No newline at end of file diff --git a/src/arch/x86_64/memory/mmap.c b/src/arch/x86_64/memory/mmap.c deleted file mode 100644 index 71d9809..0000000 --- a/src/arch/x86_64/memory/mmap.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "mmap.h" -#include "../panic.h" - -#define USABLE_REGION_SIZE 32 - -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))) - { - panic("Invalid memory map given by bootloader\n"); - } - - uint64_t offset = 0; - while (offset < info->mmap_length) - { - multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(info->mmap_addr + offset); - - if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE) - { - if (num_regions < USABLE_REGION_SIZE) - { - usable_regions[num_regions] = (memory_region_t){ - .base_address = mmmt->addr, - .length = mmmt->len, - }; - - num_regions++; - } - else - { - printf("System has more memory than the memory map can hold\n"); - break; - } - } - - offset += mmmt->size + sizeof(mmmt->size); - } -} - -memory_map_t get_memory_map() -{ - return (memory_map_t){ - .num_regions = num_regions, - .regions = usable_regions, - }; -} \ No newline at end of file diff --git a/src/arch/x86_64/memory/mmap.h b/src/arch/x86_64/memory/mmap.h deleted file mode 100644 index 54a84a7..0000000 --- a/src/arch/x86_64/memory/mmap.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "../multiboot.h" -#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/util.h b/src/arch/x86_64/util.h index 8db584c..6eb0c0f 100644 --- a/src/arch/x86_64/util.h +++ b/src/arch/x86_64/util.h @@ -68,14 +68,14 @@ enum CPUID_FEAT_EDX_PBE = 1 << 31 }; -static inline void outb(uint16_t port, uint8_t val) +static inline void outb(u16 port, u8 val) { __asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port)); } -static inline uint8_t inb(uint16_t port) +static inline u8 inb(u16 port) { - uint8_t ret; + u8 ret; __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); return ret; } @@ -85,22 +85,22 @@ static inline void io_wait() outb(0x80, 0); } -static inline void cpuid(uint32_t code, uint32_t* a, uint32_t* d) +static inline void cpuid(u32 code, u32* a, u32* d) { __asm__ volatile("cpuid" : "=a"(*a), "=d"(*d) : "a"(code) : "ecx", "ebx"); } -static inline uint64_t rdmsr(uint32_t msr) +static inline u64 rdmsr(u32 msr) { - uint32_t lo, hi; + u32 lo, hi; __asm__ volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr)); - return ((uint64_t)hi << 32) | lo; + return ((u64)hi << 32) | lo; } -static inline void wrmsr(uint32_t msr, uint64_t value) +static inline void wrmsr(u32 msr, u64 value) { - uint32_t lo = (uint32_t)value; - uint32_t hi = (uint32_t)(value >> 32); + u32 lo = (u32)value; + u32 hi = (u32)(value >> 32); __asm__ volatile("wrmsr" : : "c"(msr), "a"(lo), "d"(hi)); } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 21e158a..cc8f6b2 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,11 +1,7 @@ #include "kernel.h" -#include "pmm.h" +#include "std.h" void kernel_main() { - pmm_init(); - - uint64_t page = pmm_alloc_page(); - printf("page: %u\n", page); printf("Welcome to nub OS :)\n"); } \ No newline at end of file diff --git a/src/kernel/pmm.c b/src/kernel/pmm.c deleted file mode 100644 index 135476a..0000000 --- a/src/kernel/pmm.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "pmm.h" -#include "arch.h" - -#define BITMAP_SIZE 32768 // Supports up to 1GB of RAM -#define USABLE_REGION_SIZE 32 - -static uint8_t page_bitmap[BITMAP_SIZE]; -static uint64_t total_pages = 0; -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_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++) - { - if (page < BITMAP_SIZE * 8) - { - page_bitmap[page / 8] &= ~(1 << (page % 8)); - free_pages++; - total_pages++; - } - else - { - printf("System has more ram than the bitmap allows!\n"); - break; - } - } - } - - // Reserve first 64MB which is reserved by boot code - for (uint64_t page = 0; page < (64 * 1024 * 1024) / arch_api.page_size(); page++) - { - if (page < BITMAP_SIZE * 8) - { - if (!(page_bitmap[page / 8] & (1 << (page % 8)))) - { - page_bitmap[page / 8] |= (1 << (page % 8)); - free_pages--; - } - } - } -} - -// Returns the address of first free physical page -uint64_t pmm_alloc_page() -{ - for (size_t i = 0; i < BITMAP_SIZE; i++) - { - if (page_bitmap[i] != 0xFF) - { - for (int bit = 0; bit < 8; bit++) - { - if (!(page_bitmap[i] & (1 << bit))) - { - page_bitmap[i] |= (1 << bit); - free_pages--; - return ((i * 8 + bit) * arch_api.page_size()); - } - } - } - } - - return 0; -} - -// Frees the physical page at the specified address -void pmm_free_page(uint64_t addr) -{ - uint64_t page = addr / arch_api.page_size(); - if (page < BITMAP_SIZE * 8) - { - if (page_bitmap[page / 8] & (1 << (page % 8))) - { - page_bitmap[page / 8] &= ~(1 << (page % 8)); - free_pages++; - } - } -} \ No newline at end of file diff --git a/src/kernel/pmm.h b/src/kernel/pmm.h deleted file mode 100644 index 701f371..0000000 --- a/src/kernel/pmm.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "std.h" - -void pmm_init(); -uint64_t pmm_alloc_page(); -void pmm_free_page(uint64_t addr); \ No newline at end of file diff --git a/src/stdlib/def.h b/src/stdlib/def.h index 9c4a566..3d73020 100644 --- a/src/stdlib/def.h +++ b/src/stdlib/def.h @@ -18,29 +18,18 @@ typedef __builtin_va_list va_list; #endif typedef unsigned long size_t; -typedef long ptrdiff_t; -typedef long intptr_t; typedef unsigned long uintptr_t; #define offsetof(type, member) __builtin_offsetof(type, member) -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef signed short int16_t; -typedef unsigned short uint16_t; -typedef signed int int32_t; -typedef unsigned int uint32_t; -typedef signed long long int64_t; -typedef unsigned long long uint64_t; - -typedef uint8_t u8; -typedef int8_t i8; -typedef uint16_t u16; -typedef int16_t i16; -typedef uint32_t u32; -typedef int32_t i32; -typedef uint64_t u64; -typedef int64_t i64; +typedef unsigned char u8; +typedef signed char i8; +typedef unsigned short u16; +typedef signed short i16; +typedef unsigned int u32; +typedef signed int i32; +typedef unsigned long long u64; +typedef signed long long i64; #define INT8_MIN (-128) #define INT8_MAX 127 diff --git a/src/stdlib/io.c b/src/stdlib/io.c index 63d606f..0bb01d2 100644 --- a/src/stdlib/io.c +++ b/src/stdlib/io.c @@ -27,12 +27,12 @@ void printf(const char* fmt, ...) } else if (fmt[i] == 'c') { - char character = (char)va_arg(args, int64_t); + char character = (char)va_arg(args, u64); arch_api.putchar(character); } else if (fmt[i] == 'd') { - int64_t val = va_arg(args, int64_t); + u64 val = va_arg(args, u64); char buf[21]; itoa64(val, buf); for (size_t j = 0; buf[j] != '\0'; j++) @@ -42,7 +42,7 @@ void printf(const char* fmt, ...) } else if (fmt[i] == 'u') { - uint64_t val = va_arg(args, uint64_t); + u64 val = va_arg(args, u64); char buf[21]; uitoa64(val, buf); for (size_t j = 0; buf[j] != '\0'; j++) @@ -52,7 +52,7 @@ void printf(const char* fmt, ...) } else if (fmt[i] == 'x') { - uint64_t val = va_arg(args, uint64_t); + u64 val = va_arg(args, u64); char buf[17]; uitoa64_hex(val, buf); for (size_t j = 0; buf[j] != '\0'; j++) diff --git a/src/stdlib/mem.c b/src/stdlib/mem.c index b8b9293..9d1e642 100644 --- a/src/stdlib/mem.c +++ b/src/stdlib/mem.c @@ -1,9 +1,17 @@ #include "mem.h" -void memset(void* destination, uint8_t value, size_t length) +void memset(void* destination, u8 value, size_t length) { for (size_t i = 0; i < length; i++) { - ((uint8_t*)destination)[i] = value; + ((u8*)destination)[i] = value; + } +} + +void memcpy(void* destination, void* source, size_t length) +{ + for (size_t i = 0; i < length; i++) + { + ((u8*)destination)[i] = ((u8*)source)[i]; } } \ No newline at end of file diff --git a/src/stdlib/mem.h b/src/stdlib/mem.h index b3cfbf3..2e469d1 100644 --- a/src/stdlib/mem.h +++ b/src/stdlib/mem.h @@ -2,4 +2,5 @@ #include "std.h" -void memset(void* destination, uint8_t value, size_t length); \ No newline at end of file +void memset(void* destination, u8 value, size_t length); +void memcpy(void* destination, void* source, size_t length); \ No newline at end of file diff --git a/src/stdlib/string.c b/src/stdlib/string.c index 1cc1924..a1c0867 100644 --- a/src/stdlib/string.c +++ b/src/stdlib/string.c @@ -1,6 +1,6 @@ #include "string.h" -int kstrcmp(const char* a, const char* b) +int strcmp(const char* a, const char* b) { while ((*a != '\0' && *b != '\0') && *a == *b) { @@ -25,7 +25,7 @@ void reverse(char* str, size_t length) } } -void itoa64(int64_t value, char* buffer) +void itoa64(i64 value, char* buffer) { char temp[21]; int i = 0, j = 0; @@ -75,7 +75,7 @@ void itoa64(int64_t value, char* buffer) buffer[j] = '\0'; } -void uitoa64(uint64_t value, char* buffer) +void uitoa64(u64 value, char* buffer) { char temp[21]; int i = 0, j = 0; @@ -100,7 +100,7 @@ void uitoa64(uint64_t value, char* buffer) buffer[j] = '\0'; } -void uitoa64_hex(uint64_t value, char* buffer) +void uitoa64_hex(u64 value, char* buffer) { const char* digits = "0123456789abcdef"; char temp[17]; diff --git a/src/stdlib/string.h b/src/stdlib/string.h index 0e0ab54..8bbf4a7 100644 --- a/src/stdlib/string.h +++ b/src/stdlib/string.h @@ -3,6 +3,8 @@ #include "std.h" int strcmp(const char* a, const char* b); -void uitoa64(uint64_t value, char* buffer); -void itoa64(int64_t value, char* buffer); -void uitoa64_hex(uint64_t value, char* buffer); \ No newline at end of file +void reverse(char* str, size_t length); + +void uitoa64(u64 value, char* buffer); +void itoa64(i64 value, char* buffer); +void uitoa64_hex(u64 value, char* buffer); \ No newline at end of file