From 45a9023babb9a29a2afb213dde52fe1c2a32d567 Mon Sep 17 00:00:00 2001 From: nub31 Date: Sat, 6 Sep 2025 21:21:59 +0200 Subject: [PATCH] ... --- .clangd | 19 -------------- .vscode/c_cpp_properties.json | 19 ++++++++++++++ .vscode/settings.json | 15 ++++++++++- makefile | 12 ++++++--- src/arch/arch.h | 8 ++++-- src/arch/x86_64/arch.c | 34 +++++++++++++++++++++++- src/arch/x86_64/mem/vmm.c | 34 ------------------------ src/arch/x86_64/mem/vmm.h | 13 +++++----- src/kernel/alloc.c | 49 +++++++++++++++++++++++++++++++++++ src/kernel/alloc.h | 6 +++++ src/kernel/assert.h | 13 ++++++++++ src/kernel/kernel.c | 12 +++++++++ 12 files changed, 167 insertions(+), 67 deletions(-) delete mode 100644 .clangd create mode 100644 .vscode/c_cpp_properties.json create mode 100644 src/kernel/alloc.c create mode 100644 src/kernel/alloc.h create mode 100644 src/kernel/assert.h diff --git a/.clangd b/.clangd deleted file mode 100644 index 37513fd..0000000 --- a/.clangd +++ /dev/null @@ -1,19 +0,0 @@ -CompileFlags: - Add: - - "-target" - - "x86_64-unknown-none" - - "-ffreestanding" - - "-fno-builtin" - - "-fno-common" - - "-Wall" - - "-Wextra" - - "-Wshadow" - - "-fno-strict-aliasing" - - "-nostdinc" - - "-nostdlib" - - "-I" - - "/home/oliste/repos/nub-os/src" - - "-I" - - "/home/oliste/repos/nub-os/src/kernel" - - "-I" - - "/home/oliste/repos/nub-os/src/arch" diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..3179c58 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,19 @@ +{ + "version": 4, + "configurations": [ + { + "name": "test", + "defines": [ + "DEBUG" + ], + "includePath": [ + "src/kernel", + "src/arch", + "src" + ], + "intelliSenseMode": "linux-gcc-x64", + "compilerPath": "/usr/bin/x86_64-elf-gcc", + "cStandard": "c23" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 4fdf5e5..6c288d2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,6 +18,19 @@ "system_error": "c", "std.h": "c", "panic.h": "c", - "pmm.h": "c" + "pmm.h": "c", + "array": "cpp", + "string_view": "cpp", + "initializer_list": "cpp", + "ranges": "cpp", + "span": "cpp", + "valarray": "cpp", + "alloc.h": "c", + "arch.h": "c", + "def.h": "c", + "assert.h": "c", + "io.h": "c", + "mem.h": "c", + "string.h": "c" } } \ No newline at end of file diff --git a/makefile b/makefile index e314399..eb3ee2d 100644 --- a/makefile +++ b/makefile @@ -2,9 +2,15 @@ CC = x86_64-elf-gcc LD = x86_64-elf-ld AS = nasm -CFLAGS = -m64 -ffreestanding -nostdinc -nostdlib -fno-builtin -Wall -Wextra -Wshadow -std=c11 -I src -I src/kernel -I src/arch -g -LDFLAGS = -g -ASFLAGS = -f elf64 -g -F dwarf +# Modify these settings here for defines and debug info +CFLAGS = -g -D DEBUG +LDFLAGS = -g +ASFLAGS = -g -F dwarf + +# Do not modify +CFLAGS += -m64 -ffreestanding -nostdinc -nostdlib -fno-builtin -Wall -Wextra -Wshadow -std=c23 -I src -I src/kernel -I src/arch +LDFLAGS += +ASFLAGS += -f elf64 SRC_C := $(shell find src -name '*.c') SRC_ASM := $(shell find src -name '*.asm') diff --git a/src/arch/arch.h b/src/arch/arch.h index c21be40..20b1923 100644 --- a/src/arch/arch.h +++ b/src/arch/arch.h @@ -11,14 +11,18 @@ typedef struct const arch_console_clear_t clear; } arch_console_api_t; -typedef u64 (*arch_mem_get_page_size_t)(); +typedef size_t (*arch_mem_get_page_size_t)(); +typedef void* (*arch_mem_alloc_t)(size_t page_count); +typedef void (*arch_mem_free_t)(void* virtual_address, size_t page_count); typedef struct { const arch_mem_get_page_size_t get_page_size; + const arch_mem_alloc_t alloc; + const arch_mem_free_t free; } arch_mem_api_t; -typedef void (*arch_panic_t)(const char*); +typedef void (*arch_panic_t)(const char* msg); typedef void (*arch_enable_interrupts_t)(); typedef void (*arch_disable_interrupts_t)(); typedef void (*arch_halt_t)(); diff --git a/src/arch/x86_64/arch.c b/src/arch/x86_64/arch.c index 773fbd6..64fa22b 100644 --- a/src/arch/x86_64/arch.c +++ b/src/arch/x86_64/arch.c @@ -1,6 +1,7 @@ #include "arch.h" #include "console.h" #include "mem/pmm.h" +#include "mem/vmm.h" #include "panic.h" #include "util.h" @@ -34,13 +35,44 @@ static void arch_console_clear() console_clear(); } -static u64 arch_get_page_size() +static size_t arch_get_page_size() { return PAGE_SIZE; } +void* arch_alloc(size_t page_count) +{ + u64 virtual_address = vmm_alloc_address(page_count); + + for (size_t i = 0; i < page_count; i++) + { + u64 physical_address = pmm_alloc(); + if (!physical_address) + { + panic("Out of physical memory"); + } + + vmm_map(physical_address, virtual_address + (i * PAGE_SIZE), PTE_PRESENT | PTE_WRITABLE); + } + + return (void*)virtual_address; +} + +void arch_free(void* virtual_address, size_t page_count) +{ + for (size_t i = 0; i < page_count; i++) + { + u64 physical_address = vmm_unmap((u64)virtual_address + (i * PAGE_SIZE)); + pmm_free(physical_address); + } + + vmm_free_address((u64)virtual_address, page_count); +} + static const arch_mem_api_t arch_mem_api = { .get_page_size = arch_get_page_size, + .alloc = arch_alloc, + .free = arch_free, }; static const arch_console_api_t arch_console_api = { diff --git a/src/arch/x86_64/mem/vmm.c b/src/arch/x86_64/mem/vmm.c index 3f0d621..4a43e6f 100644 --- a/src/arch/x86_64/mem/vmm.c +++ b/src/arch/x86_64/mem/vmm.c @@ -8,11 +8,6 @@ #define PTE_MASK 0x000FFFFFFFFFF000ULL -#define PTE_PRESENT (1ULL << 0) -#define PTE_WRITABLE (1ULL << 1) -#define PTE_USER (1ULL << 2) -#define PTE_PS (1ULL << 7) - #define BITMAP_PAGE_COUNT (ADDRES_SPACE_SIZE / PAGE_SIZE) #define BITMAP_SIZE (BITMAP_PAGE_COUNT / 8) @@ -185,33 +180,4 @@ u64 vmm_unmap(u64 virtual_address) __asm__ volatile("invlpg (%0)" : : "r"(virtual_address) : "memory"); return physical_address; -} - -void* vmm_alloc(size_t page_count) -{ - u64 virtual_address = vmm_alloc_address(page_count); - - for (size_t i = 0; i < page_count; i++) - { - u64 physical_address = pmm_alloc(); - if (!physical_address) - { - panic("Out of physical memory"); - } - - vmm_map(physical_address, virtual_address + (i * PAGE_SIZE), PTE_PRESENT | PTE_WRITABLE); - } - - return (void*)virtual_address; -} - -void vmm_free(void* virtual_address, size_t page_count) -{ - for (size_t i = 0; i < page_count; i++) - { - u64 physical_address = vmm_unmap((u64)virtual_address + (i * PAGE_SIZE)); - pmm_free(physical_address); - } - - vmm_free_address((u64)virtual_address, page_count); } \ No newline at end of file diff --git a/src/arch/x86_64/mem/vmm.h b/src/arch/x86_64/mem/vmm.h index 61a610c..9837f71 100644 --- a/src/arch/x86_64/mem/vmm.h +++ b/src/arch/x86_64/mem/vmm.h @@ -6,6 +6,11 @@ // The value must be a multible of 8 #define ADDRES_SPACE_SIZE GiB(64) +#define PTE_PRESENT (1ULL << 0) +#define PTE_WRITABLE (1ULL << 1) +#define PTE_USER (1ULL << 2) +#define PTE_PS (1ULL << 7) + void vmm_init(u32 kernel_page_count); // Allocates a free page aligned block of virtual addresses @@ -19,10 +24,4 @@ void vmm_free_address(u64 virtual_address, size_t page_count); // Low level function to map a virtual address to a physical address void vmm_map(u64 physical_address, u64 virtual_address, u32 flags); // Low level function to unmap a virtual address from a physical address -u64 vmm_unmap(u64 virtual_address); - -// Allocates and maps `page_count` continuous pages and returns the virtual address of the first page -void* vmm_alloc(size_t page_count); -// Frees the pages allocated via `vmm_alloc` at the specified virtual address -// Only use this function for pages mapped via `vmm_alloc` -void vmm_free(void* virtual_address, size_t page_count); \ No newline at end of file +u64 vmm_unmap(u64 virtual_address); \ No newline at end of file diff --git a/src/kernel/alloc.c b/src/kernel/alloc.c new file mode 100644 index 0000000..3f3c7ee --- /dev/null +++ b/src/kernel/alloc.c @@ -0,0 +1,49 @@ +#include "arch.h" +#include "assert.h" + +typedef struct block_header +{ + size_t size; + bool is_free; + struct block_header* next; + struct block_header* prev; + u8 data[]; +} block_header_t; + +static block_header_t* heap_start = NULL; + +#define HEADER_SIZE sizeof(block_header_t) + +static block_header_t* find_free_block(size_t size) +{ + block_header_t* current = heap_start; + + while (current != NULL) + { + if (current->is_free && current->size >= size) + { + return current; + } + + current = current->next; + } + + return NULL; +} + +void* malloc(size_t size) +{ + // Align to pointer size + size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); + + block_header_t* block = find_free_block(size); + block->is_free = false; + return (u8*)block + HEADER_SIZE; +} + +void free(void* ptr) +{ + block_header_t* block = (block_header_t*)((u8*)ptr - HEADER_SIZE); + assert(block->is_free, "Block is already free"); + block->is_free = true; +} \ No newline at end of file diff --git a/src/kernel/alloc.h b/src/kernel/alloc.h new file mode 100644 index 0000000..1b80385 --- /dev/null +++ b/src/kernel/alloc.h @@ -0,0 +1,6 @@ +#pragma once + +#include "std.h" + +void* malloc(size_t size); +void free(void* ptr); \ No newline at end of file diff --git a/src/kernel/assert.h b/src/kernel/assert.h new file mode 100644 index 0000000..817d850 --- /dev/null +++ b/src/kernel/assert.h @@ -0,0 +1,13 @@ +#pragma once + +#include "arch.h" + +static inline void assert(bool condition, const char* msg) +{ +#if DEBUG + if (!condition) + { + arch_api.panic(msg); + } +#endif +} \ No newline at end of file diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index ec97f6f..6a98bbd 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,10 +1,22 @@ #include "kernel.h" +#include "alloc.h" #include "arch.h" +#include "assert.h" #include "std.h" void kernel_main() { + assert(false, "test"); + arch_api.enable_interrupts(); + + u64* mem = malloc(1); + *mem = 23; + + printf("%d\n", *mem); + + free(mem); + printf("Welcome to nub OS :)\n"); printf("Kernel has exited\n"); arch_api.halt();