代码分类

This commit is contained in:
2026-04-19 16:42:27 +08:00
parent 739be1d7f7
commit c21c5b327e
37 changed files with 0 additions and 103 deletions

176
clks/kernel/memory/heap.c Normal file
View File

@@ -0,0 +1,176 @@
#include <clks/heap.h>
#include <clks/string.h>
#include <clks/types.h>
#define CLKS_HEAP_ARENA_SIZE (1024ULL * 1024ULL)
#define CLKS_HEAP_ALIGN 16ULL
#define CLKS_HEAP_MAGIC 0x434C454F4E4F534FULL
struct clks_heap_block {
usize size;
clks_bool is_free;
struct clks_heap_block *next;
struct clks_heap_block *prev;
u64 magic;
};
static u8 clks_heap_arena[CLKS_HEAP_ARENA_SIZE] __attribute__((aligned(16)));
static struct clks_heap_block *clks_heap_head = CLKS_NULL;
static clks_bool clks_heap_ready = CLKS_FALSE;
static usize clks_heap_used_bytes = 0;
static u64 clks_heap_alloc_count = 0;
static u64 clks_heap_free_count = 0;
static usize clks_heap_align_up(usize value) {
return (value + (CLKS_HEAP_ALIGN - 1ULL)) & ~(CLKS_HEAP_ALIGN - 1ULL);
}
static void clks_heap_split_block(struct clks_heap_block *block, usize need_size) {
usize min_tail_size = sizeof(struct clks_heap_block) + CLKS_HEAP_ALIGN;
if (block->size < (need_size + min_tail_size)) {
return;
}
{
u8 *new_block_addr = (u8 *)block + sizeof(struct clks_heap_block) + need_size;
struct clks_heap_block *new_block = (struct clks_heap_block *)new_block_addr;
new_block->size = block->size - need_size - sizeof(struct clks_heap_block);
new_block->is_free = CLKS_TRUE;
new_block->next = block->next;
new_block->prev = block;
new_block->magic = CLKS_HEAP_MAGIC;
if (block->next != CLKS_NULL) {
block->next->prev = new_block;
}
block->next = new_block;
block->size = need_size;
}
}
static void clks_heap_merge_next(struct clks_heap_block *block) {
struct clks_heap_block *next = block->next;
if (next == CLKS_NULL) {
return;
}
if (next->is_free == CLKS_FALSE) {
return;
}
if (next->magic != CLKS_HEAP_MAGIC) {
return;
}
block->size += sizeof(struct clks_heap_block) + next->size;
block->next = next->next;
if (next->next != CLKS_NULL) {
next->next->prev = block;
}
}
void clks_heap_init(void) {
clks_memset(clks_heap_arena, 0, sizeof(clks_heap_arena));
clks_heap_head = (struct clks_heap_block *)clks_heap_arena;
clks_heap_head->size = CLKS_HEAP_ARENA_SIZE - sizeof(struct clks_heap_block);
clks_heap_head->is_free = CLKS_TRUE;
clks_heap_head->next = CLKS_NULL;
clks_heap_head->prev = CLKS_NULL;
clks_heap_head->magic = CLKS_HEAP_MAGIC;
clks_heap_used_bytes = 0;
clks_heap_alloc_count = 0;
clks_heap_free_count = 0;
clks_heap_ready = CLKS_TRUE;
}
void *clks_kmalloc(usize size) {
struct clks_heap_block *current;
usize aligned_size;
if (clks_heap_ready == CLKS_FALSE) {
return CLKS_NULL;
}
if (size == 0) {
return CLKS_NULL;
}
aligned_size = clks_heap_align_up(size);
current = clks_heap_head;
while (current != CLKS_NULL) {
if (current->magic != CLKS_HEAP_MAGIC) {
return CLKS_NULL;
}
if (current->is_free == CLKS_TRUE && current->size >= aligned_size) {
clks_heap_split_block(current, aligned_size);
current->is_free = CLKS_FALSE;
clks_heap_used_bytes += current->size;
clks_heap_alloc_count++;
return (void *)((u8 *)current + sizeof(struct clks_heap_block));
}
current = current->next;
}
return CLKS_NULL;
}
void clks_kfree(void *ptr) {
struct clks_heap_block *block;
if (clks_heap_ready == CLKS_FALSE) {
return;
}
if (ptr == CLKS_NULL) {
return;
}
block = (struct clks_heap_block *)((u8 *)ptr - sizeof(struct clks_heap_block));
if (block->magic != CLKS_HEAP_MAGIC) {
return;
}
if (block->is_free == CLKS_TRUE) {
return;
}
block->is_free = CLKS_TRUE;
if (clks_heap_used_bytes >= block->size) {
clks_heap_used_bytes -= block->size;
} else {
clks_heap_used_bytes = 0;
}
clks_heap_free_count++;
clks_heap_merge_next(block);
if (block->prev != CLKS_NULL && block->prev->is_free == CLKS_TRUE) {
clks_heap_merge_next(block->prev);
}
}
struct clks_heap_stats clks_heap_get_stats(void) {
struct clks_heap_stats stats;
stats.total_bytes = CLKS_HEAP_ARENA_SIZE - sizeof(struct clks_heap_block);
stats.used_bytes = clks_heap_used_bytes;
stats.free_bytes = stats.total_bytes - stats.used_bytes;
stats.alloc_count = clks_heap_alloc_count;
stats.free_count = clks_heap_free_count;
return stats;
}

105
clks/kernel/memory/pmm.c Normal file
View File

@@ -0,0 +1,105 @@
#include <clks/pmm.h>
#include <clks/string.h>
#include <clks/types.h>
#define CLKS_PMM_MAX_TRACKED_PAGES 262144ULL
#define CLKS_PMM_MIN_USABLE_ADDR 0x100000ULL
static u64 clks_pmm_free_stack[CLKS_PMM_MAX_TRACKED_PAGES];
static u64 clks_pmm_free_top = 0;
static u64 clks_pmm_managed_pages = 0;
static u64 clks_pmm_dropped_pages = 0;
static u64 clks_align_up_u64(u64 value, u64 alignment) {
return (value + alignment - 1ULL) & ~(alignment - 1ULL);
}
static u64 clks_align_down_u64(u64 value, u64 alignment) {
return value & ~(alignment - 1ULL);
}
void clks_pmm_init(const struct limine_memmap_response *memmap) {
u64 i;
clks_pmm_free_top = 0;
clks_pmm_managed_pages = 0;
clks_pmm_dropped_pages = 0;
clks_memset(clks_pmm_free_stack, 0, sizeof(clks_pmm_free_stack));
if (memmap == CLKS_NULL) {
return;
}
for (i = 0; i < memmap->entry_count; i++) {
const struct limine_memmap_entry *entry = memmap->entries[i];
u64 start;
u64 end;
u64 addr;
if (entry == CLKS_NULL) {
continue;
}
if (entry->type != LIMINE_MEMMAP_USABLE) {
continue;
}
start = clks_align_up_u64(entry->base, CLKS_PAGE_SIZE);
end = clks_align_down_u64(entry->base + entry->length, CLKS_PAGE_SIZE);
if (end <= start) {
continue;
}
for (addr = start; addr < end; addr += CLKS_PAGE_SIZE) {
if (addr < CLKS_PMM_MIN_USABLE_ADDR) {
continue;
}
if (clks_pmm_free_top < CLKS_PMM_MAX_TRACKED_PAGES) {
clks_pmm_free_stack[clks_pmm_free_top] = addr;
clks_pmm_free_top++;
clks_pmm_managed_pages++;
} else {
clks_pmm_dropped_pages++;
}
}
}
}
u64 clks_pmm_alloc_page(void) {
if (clks_pmm_free_top == 0) {
return 0ULL;
}
clks_pmm_free_top--;
return clks_pmm_free_stack[clks_pmm_free_top];
}
void clks_pmm_free_page(u64 phys_addr) {
if (phys_addr == 0ULL) {
return;
}
if ((phys_addr & (CLKS_PAGE_SIZE - 1ULL)) != 0ULL) {
return;
}
if (clks_pmm_free_top >= CLKS_PMM_MAX_TRACKED_PAGES) {
return;
}
clks_pmm_free_stack[clks_pmm_free_top] = phys_addr;
clks_pmm_free_top++;
}
struct clks_pmm_stats clks_pmm_get_stats(void) {
struct clks_pmm_stats stats;
stats.managed_pages = clks_pmm_managed_pages;
stats.free_pages = clks_pmm_free_top;
stats.used_pages = clks_pmm_managed_pages - clks_pmm_free_top;
stats.dropped_pages = clks_pmm_dropped_pages;
return stats;
}