#include #include #define HEAP_SIZE 0x10000 extern uint8_t __malloc_start; static uint8_t* heap = &__malloc_start; typedef struct block { size_t size; int free; struct block* next; } block; static block* free_list; static intptr_t next_virtual = 0x10000000; intptr_t compute_virtual_base() { intptr_t v = next_virtual; next_virtual += 0x1000; // or size return v; } void mem_init() { free_list = (block*)heap; free_list->size = HEAP_SIZE - sizeof(block); free_list->free = 1; free_list->next = NULL; } void* my_malloc(size_t size) { block* curr = free_list; while (curr) { if (curr->free && curr->size >= size) { if (curr->size > size + sizeof(block)) { block* newb = (block*)((uint8_t*)curr + sizeof(block) + size); newb->size = curr->size - size - sizeof(block); newb->free = 1; newb->next = curr->next; curr->next = newb; curr->size = size; } curr->free = 0; // TODO: lift off delta to a earlier stage void* phys = (uint8_t*)curr + sizeof(block); // compute delta for this allocation intptr_t delta = compute_virtual_base() - (intptr_t)phys; // apply hardware instruction assumption: asm volatile("add_delta %0, %0, %1" : "+r"(phys) : "r"(delta)); return phys; } curr = curr->next; } return NULL; } void my_free(void* ptr) { if (!ptr) return; // delta is guaranteed 0 → treat pointer as physical block* b = (block*)((uint8_t*)ptr - sizeof(block)); b->free = 1; // coalesce adjacent free blocks (pure physical heap logic) block* curr = free_list; while (curr && curr->next) { if (curr->free && curr->next->free) { curr->size += sizeof(block) + curr->next->size; curr->next = curr->next->next; } else { curr = curr->next; } } }