diff --git a/compile_flags.txt b/compile_flags.txt index fcfc9aa..5aba736 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -2,24 +2,27 @@ -Wall -Wextra -Werror --Isrc/libs +-fcolor-diagnostics -Isrc/kernel/klibs -Isrc/kernel/archs --D__ck_toolchain_value=clang --D__ck_loader_value=limine --D__ck_encoding_value=utf8 --D__ck_bits_64__ --D__ck_toolchain_clang__ --D__ck_abi_value=sysv --D__ck_sys_value=kernel --D__ck_loader_limine__ --D__ck_sys_kernel__ --D__ck_encoding_utf8__ --D__ck_abi_sysv__ +-I.cutekit/extern/cute-engineering +-Isrc/kernel/klibs/stdc-shim +-Isrc/libs -D__ck_freestanding__ --D__ck_arch_value=x86_64 +-D__ck_toolchain_value=clang -D__ck_bits_value=64 +-D__ck_loader_value=limine +-D__ck_bits_64__ +-D__ck_arch_value=x86_64 +-D__ck_sys_kernel__ +-D__ck_abi_sysv__ +-D__ck_loader_limine__ -D__ck_arch_x86_64__ +-D__ck_sys_value=kernel +-D__ck_abi_value=sysv +-D__ck_toolchain_clang__ +-D__ck_encoding_value=utf8 +-D__ck_encoding_utf8__ -ffreestanding -fno-stack-protector -mno-80387 diff --git a/project.json b/project.json index 9a9ca86..e942cd6 100644 --- a/project.json +++ b/project.json @@ -1,5 +1,11 @@ { "$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.project.v1", "type": "project", - "id": "kernel" -} \ No newline at end of file + "id": "kernel", + "extern": { + "cute-engineering/libheap": { + "git": "https://github.com/cute-engineering/libheap.git", + "tag": "v1.1.0" + } + } +} diff --git a/src/kernel/klibs/kmalloc/kmalloc.c b/src/kernel/klibs/kmalloc/kmalloc.c new file mode 100644 index 0000000..b6c4b9a --- /dev/null +++ b/src/kernel/klibs/kmalloc/kmalloc.c @@ -0,0 +1,74 @@ + +#include +#include + +#include "kmalloc.h" +#include "../../core/pmm.h" + +static void *alloc_block([[gnu::unused]] void *ctx, size_t size) +{ + PmmObj page = pmm_alloc(align_up$(size, PMM_PAGE_SIZE) / PMM_PAGE_SIZE); + + if (page.base == 0) + { + return NULL; + } + + return (void *)hal_mmap_l2h(page.base); +} + +static void free_block([[gnu::unused]] void *ctx, void *block, size_t size) +{ + PmmObj page = { + .base = hal_mmap_h2l((uintptr_t)block), + .len = align_up$(size, PMM_PAGE_SIZE), + }; + + pmm_free(page); +} + +static void hook_log([[gnu::unused]] void *ctx, [[gnu::unused]] enum HeapLogType type, + [[gnu::unused]] const char *msg, [[gnu::unused]] va_list args) +{ + return; +} + +static struct Heap heap_impl = (struct Heap){ + .alloc = alloc_block, + .free = free_block, + .log = hook_log, +}; + +static Res kmalloc_malloc(size_t size) +{ + void *ptr = heap_alloc(&heap_impl, size); + return ptr == NULL ? err$(RES_NOMEM) : uok$((uintptr_t)ptr); +} + +static Res kmalloc_free(void *ptr) +{ + heap_free(&heap_impl, ptr); + return ok$(); +} + +static Res kmalloc_realloc(void *ptr, size_t size) +{ + void *new_ptr = heap_realloc(&heap_impl, ptr, size); + return new_ptr == NULL ? err$(RES_NOMEM) : uok$((uintptr_t)new_ptr); +} + +static Res kmalloc_calloc(size_t nmemb, size_t size) +{ + void *ptr = heap_calloc(&heap_impl, nmemb, size); + return ptr == NULL ? err$(RES_NOMEM) : uok$((uintptr_t)ptr); +} + +Alloc kmalloc_acquire(void) +{ + return (Alloc){ + .malloc = kmalloc_malloc, + .free = kmalloc_free, + .realloc = kmalloc_realloc, + .calloc = kmalloc_calloc, + }; +} \ No newline at end of file diff --git a/src/kernel/klibs/kmalloc/kmalloc.h b/src/kernel/klibs/kmalloc/kmalloc.h new file mode 100644 index 0000000..b9b72d9 --- /dev/null +++ b/src/kernel/klibs/kmalloc/kmalloc.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +Alloc kmalloc_acquire(void); \ No newline at end of file diff --git a/src/libs/alloc.h b/src/libs/alloc.h new file mode 100644 index 0000000..fc29882 --- /dev/null +++ b/src/libs/alloc.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +typedef struct _Alloc +{ + Res (*realloc)(void *ptr, size_t size); + Res (*malloc)(size_t size); + Res (*free)(void *ptr); + Res (*calloc)(size_t count, size_t size); +} Alloc; + +typedef Alloc (*AllocAcquireFn)(void); + +static inline Res alloc_default_malloc(Alloc *alloc, size_t size) +{ + return alloc->realloc(NULL, size); +} + +static inline Res alloc_default_free(Alloc *alloc, void *ptr) +{ + return alloc->realloc(ptr, 0); +} + +static inline Res alloc_default_calloc(Alloc *alloc, size_t count, size_t size) +{ + Res res = alloc->realloc(NULL, count * size); + + if (res.type == RES_OK) + { + memset((void *)res.uvalue, 0, count * size); + } + + return res; +} \ No newline at end of file