feat: implement PS/2 keyboard & shell, dynamic heap (malloc/new), Zero-Copy SHM, and SMP multicore initialization

This commit is contained in:
RarDog
2026-09-02 16:58:33 +03:00
parent e7a0d2e6b1
commit 4d7ee738b6
18 changed files with 698 additions and 31 deletions
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include "stddef.h"
#include "stdint.h"
#ifdef __cplusplus
extern "C" {
#endif
void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t num, size_t size);
void *realloc(void *ptr, size_t size);
void abort(void);
void exit(int status);
#ifdef __cplusplus
}
#endif
+123
View File
@@ -0,0 +1,123 @@
#include "stdlib.h"
#include "string.h"
#include "abi/syscalls.h"
#define HEAP_CHUNK_SIZE (64 * 1024) // 64 KiB chunks from kernel
#define ALIGN16(x) (((x) + 15) & ~15)
typedef struct block_header {
size_t size;
int is_free;
struct block_header *next;
} block_header_t;
#define HEADER_SIZE sizeof(block_header_t)
static block_header_t *free_list = NULL;
void *malloc(size_t size) {
if (size == 0) return NULL;
size = ALIGN16(size);
// 1. Search free list
block_header_t *curr = free_list;
block_header_t *prev = NULL;
while (curr) {
if (curr->is_free && curr->size >= size) {
// Split block if excess size is large enough
if (curr->size >= size + HEADER_SIZE + 32) {
block_header_t *new_block = (block_header_t *)((uintptr_t)curr + HEADER_SIZE + size);
new_block->size = curr->size - size - HEADER_SIZE;
new_block->is_free = 1;
new_block->next = curr->next;
curr->size = size;
curr->next = new_block;
}
curr->is_free = 0;
return (void *)((uintptr_t)curr + HEADER_SIZE);
}
prev = curr;
curr = curr->next;
}
// 2. Request new pages from microkernel
size_t alloc_size = size + HEADER_SIZE;
if (alloc_size < HEAP_CHUNK_SIZE) {
alloc_size = HEAP_CHUNK_SIZE;
}
alloc_size = (alloc_size + 4095) & ~4095; // 4KiB page align
void *mem = sys_mem_alloc(alloc_size);
if (!mem) return NULL;
block_header_t *new_chunk = (block_header_t *)mem;
new_chunk->size = alloc_size - HEADER_SIZE;
new_chunk->is_free = 1;
new_chunk->next = NULL;
if (prev) {
prev->next = new_chunk;
} else {
free_list = new_chunk;
}
// Now re-allocate from the new chunk
return malloc(size);
}
void free(void *ptr) {
if (!ptr) return;
block_header_t *header = (block_header_t *)((uintptr_t)ptr - HEADER_SIZE);
header->is_free = 1;
// Coalesce adjacent free blocks
block_header_t *curr = free_list;
while (curr && curr->next) {
if (curr->is_free && curr->next->is_free) {
curr->size += HEADER_SIZE + curr->next->size;
curr->next = curr->next->next;
} else {
curr = curr->next;
}
}
}
void *calloc(size_t num, size_t size) {
size_t total = num * size;
void *ptr = malloc(total);
if (ptr) {
memset(ptr, 0, total);
}
return ptr;
}
void *realloc(void *ptr, size_t size) {
if (!ptr) return malloc(size);
if (size == 0) {
free(ptr);
return NULL;
}
block_header_t *header = (block_header_t *)((uintptr_t)ptr - HEADER_SIZE);
if (header->size >= size) {
return ptr;
}
void *new_ptr = malloc(size);
if (new_ptr) {
memcpy(new_ptr, ptr, header->size);
free(ptr);
}
return new_ptr;
}
void abort(void) {
sys_exit(-1);
}
void exit(int status) {
sys_exit(status);
}