feat: implement PS/2 keyboard & shell, dynamic heap (malloc/new), Zero-Copy SHM, and SMP multicore initialization
This commit is contained in:
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,5 +1,31 @@
|
||||
#include "../include/ipc.hpp"
|
||||
#include "stdlib.h"
|
||||
|
||||
// Global C++ Operator Overloads for Ring 3 Userspace
|
||||
void* operator new(size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void* operator new[](size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr) noexcept {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr) noexcept {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr, size_t) noexcept {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr, size_t) noexcept {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
namespace ipc {
|
||||
// Shared library routines if needed
|
||||
// Modern RAII methods if needed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user