feat: kmalloc + slab allocator
This commit is contained in:
parent
167c99c215
commit
01773cb062
41 changed files with 454 additions and 32 deletions
meta/targets
src
kernel
core
hal
kmalloc
manifest.jsonmanifest.sync-conflict-20250504-125402-L4Z4EYX.jsonmod.cmod.hmod.sync-conflict-20250504-125402-L4Z4EYX.h
libs/libc
pmm
sched
task
libs
allocators
handover/dtb
helpers
traits
|
@ -34,9 +34,7 @@ SECTIONS {
|
||||||
|
|
||||||
. += CONSTANT(MAXPAGESIZE);
|
. += CONSTANT(MAXPAGESIZE);
|
||||||
|
|
||||||
stack_start_addr = .;
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
. += 128 * 1024; /* 128KB */
|
. += 128 * 1024; /* 128KB */
|
||||||
__stack_top = .;
|
__stack_top = .;
|
||||||
stack_end_addr = .;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
|
#include <allocators/slab.h>
|
||||||
#include <fmt>
|
#include <fmt>
|
||||||
#include <hal>
|
#include <hal>
|
||||||
|
#include <kmalloc>
|
||||||
#include <logger>
|
#include <logger>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
void kmain(void) {
|
void kmain(void) {
|
||||||
info$("Hello, World!");
|
kmalloc_init();
|
||||||
|
|
||||||
|
Allocator kmalloc = kmalloc_allocator();
|
||||||
|
char* hello = (char*)kmalloc.alloc(&kmalloc, 14);
|
||||||
|
memset(hello, 0, 14);
|
||||||
|
strncpy(hello, "Hello, World!", 13);
|
||||||
|
info$("%s", hello);
|
||||||
|
kmalloc.free(&kmalloc, hello, 14);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
"id": "hal",
|
"id": "hal",
|
||||||
"requires": [
|
"requires": [
|
||||||
"hal-impl",
|
"hal-impl",
|
||||||
"heap"
|
"allocators"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <dtb>
|
#include <dtb>
|
||||||
|
#include <helpers/errors.h>
|
||||||
#include <io>
|
#include <io>
|
||||||
|
|
||||||
void hal_setup(void);
|
void hal_setup(void);
|
||||||
|
@ -16,15 +17,17 @@ typedef enum {
|
||||||
HAL_MAP_HUGE = 1 << 4,
|
HAL_MAP_HUGE = 1 << 4,
|
||||||
} HalMapFlags;
|
} HalMapFlags;
|
||||||
|
|
||||||
typedef enum {
|
#define MAPPING_ERRORS(ERR) \
|
||||||
HAL_MAP_OK,
|
ERR(HAL_MAP_OK, "Operation completed successfully") \
|
||||||
HAL_MAP_PHYS_UNALIGNED,
|
ERR(HAL_MAP_PHYS_UNALIGNED, "Physical address is unaligned") \
|
||||||
HAL_MAP_VIRT_UNALIGNED,
|
ERR(HAL_MAP_VIRT_UNALIGNED, "Virtual address is unaligned") \
|
||||||
HAL_MAP_COULDNT_ALLOCATE,
|
ERR(HAL_MAP_COULDNT_ALLOCATE, "Couldn't allocate memory") \
|
||||||
HAL_MAP_ALREADY_MAPPED,
|
ERR(HAL_MAP_ALREADY_MAPPED, "Page is already mapped")
|
||||||
} HalMappingError;
|
|
||||||
|
|
||||||
typedef struct _page HalPage;
|
DECLARE_ERROR_ENUM(HalMapping, MAPPING_ERRORS)
|
||||||
|
DECLARE_ERROR_STRING(HalMapping, MAPPING_ERRORS)
|
||||||
|
|
||||||
|
typedef struct _hal_page HalPage;
|
||||||
|
|
||||||
HalMappingError hal_map_page(HalPage page, uintptr_t virt, uintptr_t phys, size_t length, uint8_t flags);
|
HalMappingError hal_map_page(HalPage page, uintptr_t virt, uintptr_t phys, size_t length, uint8_t flags);
|
||||||
|
|
||||||
|
@ -32,6 +35,16 @@ void hal_switch_space(HalPage space);
|
||||||
|
|
||||||
size_t page_size(void);
|
size_t page_size(void);
|
||||||
|
|
||||||
|
void* hal_mmap_l2h(uintptr_t addr);
|
||||||
|
|
||||||
|
void* hal_mmap_h2l(uintptr_t addr);
|
||||||
|
|
||||||
|
/* === TASKS & SCHEDULING === */
|
||||||
|
|
||||||
|
typedef struct _hal_context HalContext;
|
||||||
|
|
||||||
|
HalContext* hal_create_context(void);
|
||||||
|
|
||||||
/* === I/O === */
|
/* === I/O === */
|
||||||
|
|
||||||
void hal_putc(int ch);
|
void hal_putc(int ch);
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
#include <allocators/bump.h>
|
||||||
|
#include <allocators/slab.h>
|
||||||
#include <dtb>
|
#include <dtb>
|
||||||
#include <hal>
|
#include <hal>
|
||||||
#include <handover-dtb>
|
#include <handover-dtb>
|
||||||
#include <heap/bump.h>
|
|
||||||
#include <helpers/mem.h>
|
#include <helpers/mem.h>
|
||||||
#include <logger>
|
#include <logger>
|
||||||
#include <pmm>
|
#include <pmm>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
.section .text.boot
|
.section .text.boot
|
||||||
|
|
||||||
.global rv32_start
|
.global rv32_start
|
||||||
.type rv32_start, @function
|
.type rv32_start, @function
|
||||||
|
|
||||||
|
|
||||||
.global _start
|
.global _start
|
||||||
_start:
|
_start:
|
||||||
mv ra, zero
|
mv ra, zero
|
||||||
|
|
8
src/kernel/hal/rv32/context.c
Normal file
8
src/kernel/hal/rv32/context.c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include <hal>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
HalContext* hal_context_create(void) {
|
||||||
|
return NULL;
|
||||||
|
}
|
9
src/kernel/hal/rv32/context.h
Normal file
9
src/kernel/hal/rv32/context.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <hal>
|
||||||
|
|
||||||
|
#include "regs.h"
|
||||||
|
|
||||||
|
struct _hal_context {
|
||||||
|
Stackframe frame;
|
||||||
|
};
|
|
@ -42,7 +42,7 @@ static void panic_handler(Stackframe* frame, uint32_t scause, uint32_t stval, ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void exception_handler(Stackframe* frame) {
|
Stackframe* exception_handler(Stackframe* frame) {
|
||||||
uint32_t scause = read_csr$(scause);
|
uint32_t scause = read_csr$(scause);
|
||||||
uint32_t stval = read_csr$(stval);
|
uint32_t stval = read_csr$(stval);
|
||||||
uint32_t user_pc = read_csr$(sepc);
|
uint32_t user_pc = read_csr$(sepc);
|
||||||
|
@ -52,4 +52,6 @@ void exception_handler(Stackframe* frame) {
|
||||||
} else {
|
} else {
|
||||||
panic_handler(frame, scause, stval, user_pc);
|
panic_handler(frame, scause, stval, user_pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
extern void interrupt_kernel(void);
|
extern void interrupt_kernel(void);
|
||||||
|
|
||||||
void exception_handler(Stackframe* frame);
|
Stackframe* exception_handler(Stackframe* frame);
|
||||||
|
|
|
@ -40,6 +40,7 @@ interrupt_kernel:
|
||||||
|
|
||||||
mv a0, sp
|
mv a0, sp
|
||||||
call exception_handler
|
call exception_handler
|
||||||
|
mv sp, a0
|
||||||
|
|
||||||
lw ra, 4 * 0(sp)
|
lw ra, 4 * 0(sp)
|
||||||
lw gp, 4 * 1(sp)
|
lw gp, 4 * 1(sp)
|
||||||
|
|
|
@ -13,3 +13,11 @@ void hal_brkpoint(void) {
|
||||||
size_t page_size(void) {
|
size_t page_size(void) {
|
||||||
return 4096;
|
return 4096;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* hal_mmap_l2h(uintptr_t addr) {
|
||||||
|
return (void*)addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* hal_mmap_h2l(uintptr_t addr) {
|
||||||
|
return (void*)addr;
|
||||||
|
}
|
||||||
|
|
|
@ -7,5 +7,5 @@
|
||||||
"sys": ["kernel"]
|
"sys": ["kernel"]
|
||||||
},
|
},
|
||||||
"provides": ["hal-impl"],
|
"provides": ["hal-impl"],
|
||||||
"requires": ["dtb", "pmm", "handover-dtb"]
|
"requires": ["dtb", "pmm", "handover-dtb", "kmalloc"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <pmm>
|
#include <pmm>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "base/mod.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
|
|
||||||
|
@ -13,8 +14,7 @@ extern uint8_t rodata_start_addr[];
|
||||||
extern uint8_t rodata_end_addr[];
|
extern uint8_t rodata_end_addr[];
|
||||||
extern uint8_t data_start_addr[];
|
extern uint8_t data_start_addr[];
|
||||||
extern uint8_t data_end_addr[];
|
extern uint8_t data_end_addr[];
|
||||||
extern uint8_t stack_start_addr[];
|
extern uint8_t __stack_top[];
|
||||||
extern uint8_t stack_end_addr[];
|
|
||||||
|
|
||||||
static uint32_t* kernel_page_table = NULL;
|
static uint32_t* kernel_page_table = NULL;
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ void hal_switch_space(HalPage space) {
|
||||||
__asm__ volatile("sfence.vma");
|
__asm__ volatile("sfence.vma");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Use new error from <helpers/errors.h>
|
||||||
void paging_init(void) {
|
void paging_init(void) {
|
||||||
PhysObj page_phys = pmm_alloc(page_size());
|
PhysObj page_phys = pmm_alloc(page_size());
|
||||||
if (page_phys.base == 0) {
|
if (page_phys.base == 0) {
|
||||||
|
@ -107,7 +108,7 @@ void paging_init(void) {
|
||||||
size_t text_end = align_up$((uintptr_t)text_end_addr, page_size());
|
size_t text_end = align_up$((uintptr_t)text_end_addr, page_size());
|
||||||
HalMappingError err = hal_map_page((HalPage){kernel_page_table}, text_start, text_start, text_end - text_start, HAL_MAP_READ | HAL_MAP_EXEC);
|
HalMappingError err = hal_map_page((HalPage){kernel_page_table}, text_start, text_start, text_end - text_start, HAL_MAP_READ | HAL_MAP_EXEC);
|
||||||
if (err != HAL_MAP_OK) {
|
if (err != HAL_MAP_OK) {
|
||||||
error$("Couldn't map kernel text, cause: %d", err);
|
error$("Couldn't map kernel text, cause: %s", HalMappingErrorString(err));
|
||||||
hal_brkpoint();
|
hal_brkpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ void paging_init(void) {
|
||||||
size_t rodata_end = align_up$((uintptr_t)rodata_end_addr, page_size());
|
size_t rodata_end = align_up$((uintptr_t)rodata_end_addr, page_size());
|
||||||
err = hal_map_page((HalPage){kernel_page_table}, rodata_start, rodata_start, rodata_end - rodata_start, HAL_MAP_READ);
|
err = hal_map_page((HalPage){kernel_page_table}, rodata_start, rodata_start, rodata_end - rodata_start, HAL_MAP_READ);
|
||||||
if (err != HAL_MAP_OK) {
|
if (err != HAL_MAP_OK) {
|
||||||
error$("Couldn't map kernel rodata, cause: %d", err);
|
error$("Couldn't map kernel rodata, cause: %s", HalMappingErrorString(err));
|
||||||
hal_brkpoint();
|
hal_brkpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,18 +124,23 @@ void paging_init(void) {
|
||||||
size_t data_end = align_up$((uintptr_t)data_end_addr, page_size());
|
size_t data_end = align_up$((uintptr_t)data_end_addr, page_size());
|
||||||
err = hal_map_page((HalPage){kernel_page_table}, data_start, data_start, data_end - data_start, HAL_MAP_READ | HAL_MAP_WRITE);
|
err = hal_map_page((HalPage){kernel_page_table}, data_start, data_start, data_end - data_start, HAL_MAP_READ | HAL_MAP_WRITE);
|
||||||
if (err != HAL_MAP_OK) {
|
if (err != HAL_MAP_OK) {
|
||||||
error$("Couldn't map kernel data, cause: %d", err);
|
error$("Couldn't map kernel data, cause: %s", HalMappingErrorString(err));
|
||||||
hal_brkpoint();
|
hal_brkpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t stack_start = align_down$((uintptr_t)stack_start_addr, page_size());
|
size_t stack_start = align_down$((uintptr_t)__stack_top - kib$(128), page_size());
|
||||||
size_t stack_end = align_up$((uintptr_t)stack_end_addr, page_size());
|
size_t stack_end = align_up$((uintptr_t)__stack_top, page_size());
|
||||||
err = hal_map_page((HalPage){kernel_page_table}, stack_start, stack_start, stack_end - stack_start, HAL_MAP_READ | HAL_MAP_WRITE);
|
err = hal_map_page((HalPage){kernel_page_table}, stack_start, stack_start, stack_end - stack_start, HAL_MAP_READ | HAL_MAP_WRITE);
|
||||||
if (err != HAL_MAP_OK) {
|
if (err != HAL_MAP_OK) {
|
||||||
error$("Couldn't map kernel stack, cause: %d", err);
|
error$("Couldn't map kernel stack, cause: %s", HalMappingErrorString(err));
|
||||||
hal_brkpoint();
|
hal_brkpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HandoverRecord rec;
|
||||||
|
handover_foreach_record(handover(), rec) {
|
||||||
|
hal_map_page((HalPage){kernel_page_table}, rec.start, rec.start, rec.size, HAL_MAP_READ | HAL_MAP_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
debug$("Switching to page table %p", kernel_page_table);
|
debug$("Switching to page table %p", kernel_page_table);
|
||||||
hal_switch_space((HalPage){kernel_page_table});
|
hal_switch_space((HalPage){kernel_page_table});
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ enum mapping_flags {
|
||||||
MAPPING_USER = 1 << 4,
|
MAPPING_USER = 1 << 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _page {
|
struct _hal_page {
|
||||||
uint32_t* ptr;
|
uint32_t* ptr;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
9
src/kernel/kmalloc/manifest.json
Normal file
9
src/kernel/kmalloc/manifest.json
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
|
||||||
|
"type": "lib",
|
||||||
|
"id": "kmalloc",
|
||||||
|
"requires": [
|
||||||
|
"allocators",
|
||||||
|
"traits"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
|
||||||
|
"id": "kmalloc",
|
||||||
|
"type": "lib",
|
||||||
|
"requires": [
|
||||||
|
"allocators",
|
||||||
|
"traits"
|
||||||
|
]
|
||||||
|
}
|
70
src/kernel/kmalloc/mod.c
Normal file
70
src/kernel/kmalloc/mod.c
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#include <allocators/slab.h>
|
||||||
|
#include <logger>
|
||||||
|
#include <pmm>
|
||||||
|
|
||||||
|
static SlabAllocator slabs[6] = {0};
|
||||||
|
|
||||||
|
void kmalloc_init(void) {
|
||||||
|
Allocator pmm = pmm_allocator();
|
||||||
|
|
||||||
|
slabs[0] = slab_create(8, &pmm);
|
||||||
|
slabs[1] = slab_create(16, &pmm);
|
||||||
|
slabs[2] = slab_create(32, &pmm);
|
||||||
|
slabs[3] = slab_create(64, &pmm);
|
||||||
|
slabs[4] = slab_create(128, &pmm);
|
||||||
|
slabs[5] = slab_create(256, &pmm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* _alloc(__attribute__((unused)) void* ctx, size_t len) {
|
||||||
|
Allocator* alloc = NULL;
|
||||||
|
|
||||||
|
if (len <= 8) {
|
||||||
|
alloc = &slabs[0].base;
|
||||||
|
} else if (len <= 16) {
|
||||||
|
alloc = &slabs[1].base;
|
||||||
|
} else if (len <= 32) {
|
||||||
|
alloc = &slabs[2].base;
|
||||||
|
} else if (len <= 64) {
|
||||||
|
alloc = &slabs[3].base;
|
||||||
|
} else if (len <= 128) {
|
||||||
|
alloc = &slabs[4].base;
|
||||||
|
} else if (len <= 256) {
|
||||||
|
alloc = &slabs[5].base;
|
||||||
|
} else {
|
||||||
|
Allocator pmm = pmm_allocator();
|
||||||
|
alloc = &pmm;
|
||||||
|
}
|
||||||
|
|
||||||
|
return alloc->alloc(alloc, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _free(__attribute__((unused)) void* ctx, void* ptr, size_t len) {
|
||||||
|
Allocator* alloc = NULL;
|
||||||
|
|
||||||
|
if (len <= 8) {
|
||||||
|
alloc = &slabs[0].base;
|
||||||
|
} else if (len <= 16) {
|
||||||
|
alloc = &slabs[1].base;
|
||||||
|
} else if (len <= 32) {
|
||||||
|
alloc = &slabs[2].base;
|
||||||
|
} else if (len <= 64) {
|
||||||
|
alloc = &slabs[3].base;
|
||||||
|
} else if (len <= 128) {
|
||||||
|
alloc = &slabs[4].base;
|
||||||
|
} else if (len <= 256) {
|
||||||
|
alloc = &slabs[5].base;
|
||||||
|
} else {
|
||||||
|
Allocator pmm = pmm_allocator();
|
||||||
|
alloc = &pmm;
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc->free(alloc, ptr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
Allocator kmalloc_allocator(void) {
|
||||||
|
return (Allocator){
|
||||||
|
.alloc = _alloc,
|
||||||
|
.free = _free,
|
||||||
|
.realloc = NULL,
|
||||||
|
};
|
||||||
|
}
|
7
src/kernel/kmalloc/mod.h
Normal file
7
src/kernel/kmalloc/mod.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <traits/allocator.h>
|
||||||
|
|
||||||
|
void kmalloc_init(void);
|
||||||
|
|
||||||
|
Allocator kmalloc_allocator(void);
|
|
@ -0,0 +1 @@
|
||||||
|
#pragma once
|
|
@ -48,3 +48,14 @@ void* memcpy(void* s1, void const* s2, size_t n) {
|
||||||
|
|
||||||
return s1;
|
return s1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* strncpy(char* s1, char const* s2, size_t n) {
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while (s2[i] != 0 && i < n) {
|
||||||
|
s1[i] = s2[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s1;
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
size_t strlen(char const* s);
|
size_t strlen(char const* s);
|
||||||
|
|
||||||
void* memset(void* s, int c, size_t n);
|
void* memset(void* s, int c, size_t n);
|
||||||
|
|
||||||
int strncmp(char const* s1, char const* s2, size_t n);
|
int strncmp(char const* s1, char const* s2, size_t n);
|
||||||
|
|
||||||
|
char* strncpy(char* s1, char const* s2, size_t n);
|
||||||
|
|
||||||
void* memcpy(void* s1, void const* s2, size_t n);
|
void* memcpy(void* s1, void const* s2, size_t n);
|
||||||
|
|
7
src/kernel/libs/libc/unistd.c
Normal file
7
src/kernel/libs/libc/unistd.c
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include <hal>
|
||||||
|
|
||||||
|
#include "unistd.h"
|
||||||
|
|
||||||
|
int getpagesize(void) {
|
||||||
|
return page_size();
|
||||||
|
}
|
3
src/kernel/libs/libc/unistd.h
Normal file
3
src/kernel/libs/libc/unistd.h
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
int getpagesize(void);
|
|
@ -4,6 +4,7 @@
|
||||||
#include <logger>
|
#include <logger>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "base/mod.h"
|
||||||
#include "mod.h"
|
#include "mod.h"
|
||||||
|
|
||||||
static PmmBitmap bitmap = {0};
|
static PmmBitmap bitmap = {0};
|
||||||
|
@ -50,6 +51,13 @@ void pmm_init(void) {
|
||||||
if (record.tag == HANDOVER_FREE && record.size >= bitmap.len) {
|
if (record.tag == HANDOVER_FREE && record.size >= bitmap.len) {
|
||||||
debug$("Bitmap base: %p", record.start);
|
debug$("Bitmap base: %p", record.start);
|
||||||
bitmap.bitmap = (uint8_t*)record.start;
|
bitmap.bitmap = (uint8_t*)record.start;
|
||||||
|
|
||||||
|
handover_append(handover(), (HandoverRecord){
|
||||||
|
.tag = HANDOVER_RESERVED,
|
||||||
|
.start = record.start,
|
||||||
|
.size = bitmap.len,
|
||||||
|
});
|
||||||
|
|
||||||
record.start += bitmap.len;
|
record.start += bitmap.len;
|
||||||
record.size -= bitmap.len;
|
record.size -= bitmap.len;
|
||||||
break;
|
break;
|
||||||
|
@ -109,3 +117,27 @@ PhysObj pmm_alloc(size_t len) {
|
||||||
void pmm_free(PhysObj obj) {
|
void pmm_free(PhysObj obj) {
|
||||||
pmm_mark_free(obj.base, obj.len);
|
pmm_mark_free(obj.base, obj.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// === ALLOCATOR ===
|
||||||
|
|
||||||
|
static void* _alloc(__attribute__((unused)) void* ctx, size_t len) {
|
||||||
|
PhysObj obj = pmm_alloc(len);
|
||||||
|
if (obj.len == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hal_mmap_l2h(obj.base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _free(__attribute__((unused)) void* ctx, void* ptr, size_t len) {
|
||||||
|
PhysObj obj = {.base = (uintptr_t)hal_mmap_h2l((uintptr_t)ptr), .len = len};
|
||||||
|
pmm_free(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
Allocator pmm_allocator(void) {
|
||||||
|
return (Allocator){
|
||||||
|
.alloc = _alloc,
|
||||||
|
.free = _free,
|
||||||
|
.realloc = NULL,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <traits/allocator.h>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -25,3 +26,7 @@ struct pmm_alloc_param {
|
||||||
PhysObj pmm_alloc(size_t pages);
|
PhysObj pmm_alloc(size_t pages);
|
||||||
|
|
||||||
void pmm_init(void);
|
void pmm_init(void);
|
||||||
|
|
||||||
|
void pmm_free(PhysObj obj);
|
||||||
|
|
||||||
|
Allocator pmm_allocator(void);
|
||||||
|
|
6
src/kernel/sched/manifest.json
Normal file
6
src/kernel/sched/manifest.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
|
||||||
|
"type": "lib",
|
||||||
|
"id": "sched",
|
||||||
|
"requires": []
|
||||||
|
}
|
7
src/kernel/sched/mod.c
Normal file
7
src/kernel/sched/mod.c
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include "mod.h"
|
||||||
|
|
||||||
|
static size_t pid = 0;
|
||||||
|
|
||||||
|
size_t sched_next_pid(void) {
|
||||||
|
return pid++;
|
||||||
|
}
|
7
src/kernel/sched/mod.h
Normal file
7
src/kernel/sched/mod.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void sched_init(void);
|
||||||
|
|
||||||
|
size_t sched_next_pid(void);
|
6
src/kernel/task/manifest.json
Normal file
6
src/kernel/task/manifest.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
|
||||||
|
"type": "lib",
|
||||||
|
"id": "task",
|
||||||
|
"requires": ["sched"]
|
||||||
|
}
|
23
src/kernel/task/mod.c
Normal file
23
src/kernel/task/mod.c
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include <helpers/math.h>
|
||||||
|
#include <sched>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mod.h"
|
||||||
|
|
||||||
|
TaskError task_new(char const* name, HalPage* page_table, uintptr_t ip, Allocator* alloc) {
|
||||||
|
Task* task = alloc->alloc(alloc, sizeof(Task));
|
||||||
|
|
||||||
|
if (task == NULL) {
|
||||||
|
return TASK_COULDNT_ALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page_table == NULL) {
|
||||||
|
return TASK_PAGE_TABLE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
task->pid = sched_next_pid();
|
||||||
|
task->page_table = page_table;
|
||||||
|
strncpy(task->name, name, min$(strlen(name), TASK_NAME_LIMIT - 1));
|
||||||
|
|
||||||
|
return TASK_OK;
|
||||||
|
}
|
25
src/kernel/task/mod.h
Normal file
25
src/kernel/task/mod.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <hal>
|
||||||
|
#include <helpers/errors.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <traits/allocator.h>
|
||||||
|
|
||||||
|
#define TASK_NAME_LIMIT (256)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[TASK_NAME_LIMIT];
|
||||||
|
size_t pid;
|
||||||
|
HalPage* page_table;
|
||||||
|
HalContext* context;
|
||||||
|
} Task;
|
||||||
|
|
||||||
|
#define TASK_ERRORS(ERR) \
|
||||||
|
ERR(TASK_OK, "Operation completed successfully") \
|
||||||
|
ERR(TASK_COULDNT_ALLOC, "Couldn't allocate memory") \
|
||||||
|
ERR(TASK_PAGE_TABLE_NULL, "The provided page table is NULL")
|
||||||
|
|
||||||
|
DECLARE_ERROR_ENUM(Task, TASK_ERRORS)
|
||||||
|
DECLARE_ERROR_STRING(Task, TASK_ERRORS)
|
||||||
|
|
||||||
|
TaskError task_new(char const* name, HalPage* page_table, uintptr_t ip, Allocator* alloc);
|
|
@ -1,7 +1,8 @@
|
||||||
#include "bump.h"
|
|
||||||
#include <helpers/mem.h>
|
#include <helpers/mem.h>
|
||||||
#include <logger>
|
#include <logger>
|
||||||
|
|
||||||
|
#include "bump.h"
|
||||||
|
|
||||||
static void* alloc(void* ctx, size_t len) {
|
static void* alloc(void* ctx, size_t len) {
|
||||||
size_t aligned_len = len & 7 ? align_up$(len, 8) : len;
|
size_t aligned_len = len & 7 ? align_up$(len, 8) : len;
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ static void* alloc(void* ctx, size_t len) {
|
||||||
return (void*)ptr;
|
return (void*)ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free(void* ctx, __attribute__((unused)) void* ptr) {
|
static void free(void* ctx, __attribute__((unused)) void* ptr, __attribute__((unused)) size_t len) {
|
||||||
BumpAllocator* self = (BumpAllocator*)ctx;
|
BumpAllocator* self = (BumpAllocator*)ctx;
|
||||||
self->allocations--;
|
self->allocations--;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
|
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
|
||||||
"id": "heap",
|
"id": "allocators",
|
||||||
"type": "lib"
|
"type": "lib"
|
||||||
}
|
}
|
91
src/libs/allocators/slab.c
Normal file
91
src/libs/allocators/slab.c
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#include <allocators/bump.h>
|
||||||
|
#include <helpers/mem.h>
|
||||||
|
#include <logger>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "slab.h"
|
||||||
|
|
||||||
|
static size_t page_amount(size_t size) {
|
||||||
|
if (size <= 64) {
|
||||||
|
return 64;
|
||||||
|
} else if (size <= 128) {
|
||||||
|
return 32;
|
||||||
|
} else if (size <= 512) {
|
||||||
|
return 16;
|
||||||
|
} else if (size <= 1024) {
|
||||||
|
return 8;
|
||||||
|
} else {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* _alloc(void* ctx, __attribute__((unused)) size_t len) {
|
||||||
|
SlabAllocator* alloc = (SlabAllocator*)ctx;
|
||||||
|
if (alloc->root == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ptr = (void*)(alloc->root->ptr + sizeof(Slab));
|
||||||
|
alloc->root = alloc->root->next;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _free(void* ctx, void* ptr, __attribute__((unused)) size_t len) {
|
||||||
|
SlabAllocator* alloc = (SlabAllocator*)ctx;
|
||||||
|
Slab* free = (Slab*)((uintptr_t)ptr - sizeof(Slab));
|
||||||
|
|
||||||
|
if (free->ptr + sizeof(Slab) != (uintptr_t)ptr) {
|
||||||
|
error$("Invalid free %p != %p", free->ptr, ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slab* slab = alloc->root;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (slab->next == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
slab = slab->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
slab->next = free;
|
||||||
|
}
|
||||||
|
|
||||||
|
SlabAllocator slab_create(uintptr_t size, Allocator* page_alloc) {
|
||||||
|
size_t n_page = page_amount(size + sizeof(Slab));
|
||||||
|
void* page = page_alloc->alloc(page_alloc, n_page * getpagesize());
|
||||||
|
|
||||||
|
if (page == NULL) {
|
||||||
|
return (SlabAllocator){0};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sz = align_up$(sizeof(Slab) + size, sizeof(void*));
|
||||||
|
BumpAllocator bump = bump_allocator_create(page, n_page * getpagesize());
|
||||||
|
Slab* root = bump.base.alloc(&bump, sz);
|
||||||
|
root->ptr = (uintptr_t)root;
|
||||||
|
|
||||||
|
Slab* slab = root;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
void* ptr = bump.base.alloc(&bump, sz);
|
||||||
|
|
||||||
|
if (ptr == NULL) {
|
||||||
|
slab->next = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
slab->next = ptr;
|
||||||
|
slab->next->ptr = (uintptr_t)ptr;
|
||||||
|
slab = slab->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SlabAllocator){
|
||||||
|
.base = {
|
||||||
|
.alloc = _alloc,
|
||||||
|
.free = _free,
|
||||||
|
.realloc = 0,
|
||||||
|
},
|
||||||
|
.root = root,
|
||||||
|
};
|
||||||
|
}
|
18
src/libs/allocators/slab.h
Normal file
18
src/libs/allocators/slab.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <traits/allocator.h>
|
||||||
|
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
|
||||||
|
typedef struct _slab {
|
||||||
|
uintptr_t ptr;
|
||||||
|
struct _slab* next;
|
||||||
|
} Slab;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Allocator base;
|
||||||
|
Slab* root;
|
||||||
|
} SlabAllocator;
|
||||||
|
|
||||||
|
SlabAllocator slab_create(uintptr_t size, Allocator* page_alloc);
|
|
@ -1,10 +1,7 @@
|
||||||
#include <helpers/mem.h>
|
#include <helpers/mem.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "handover/base/mod.h"
|
|
||||||
#include "logger/mod.h"
|
|
||||||
#include "mod.h"
|
#include "mod.h"
|
||||||
|
|
||||||
static DTBNode* dtb_root = NULL;
|
static DTBNode* dtb_root = NULL;
|
||||||
|
|
18
src/libs/helpers/errors.h
Normal file
18
src/libs/helpers/errors.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ENUM_ITEM(name, msg) name,
|
||||||
|
#define STRINGIFY(name, msg) #msg,
|
||||||
|
|
||||||
|
#define DECLARE_ERROR_ENUM(PREFIX, LIST) \
|
||||||
|
typedef enum { \
|
||||||
|
LIST(ENUM_ITEM) \
|
||||||
|
} PREFIX##Error;
|
||||||
|
|
||||||
|
#define DECLARE_ERROR_STRING(PREFIX, LIST) \
|
||||||
|
__attribute__((used)) static const char* PREFIX##ErrorStrings[] = { \
|
||||||
|
LIST(STRINGIFY) \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
inline static char const* PREFIX##ErrorString(PREFIX##Error err) { \
|
||||||
|
return PREFIX##ErrorStrings[err]; \
|
||||||
|
}
|
5
src/libs/helpers/math.h
Normal file
5
src/libs/helpers/math.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define min$(x, y) ((x) < (y) ? (x) : (y))
|
||||||
|
|
||||||
|
#define max$(x, y) ((x) > (y) ? (x) : (y))
|
|
@ -5,5 +5,5 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void* (*alloc)(void* ctx, size_t len);
|
void* (*alloc)(void* ctx, size_t len);
|
||||||
void* (*realloc)(void* ctx, void* ptr, size_t len);
|
void* (*realloc)(void* ctx, void* ptr, size_t len);
|
||||||
void (*free)(void* ctx, void* ptr);
|
void (*free)(void* ctx, void* ptr, size_t len);
|
||||||
} Allocator;
|
} Allocator;
|
||||||
|
|
Loading…
Add table
Reference in a new issue