Memory Manager
Posted: Thu Nov 03, 2022 12:30 pm
I'm trying to use this bitmap heap, but I get a page fault when using it. I would add this mini debugger, but I don't know how I would do that. Could someone help me fix the page fault (and maybe help me add the mini debugger to my OS)? Here is my kernel code:
Here is my memory code:
Any help would be greatly appreciated.
Code: Select all
#include <kernel/tty.h>
#include <kernel/io.h>
#include <kernel/gdt.h>
#include <kernel/ints.h>
#include <kernel/dbg.h>
#include <kernel/stdio.h>
#include <kernel/mem.h>
void _kernel_end(void);
uintptr_t vaddr = (uintptr_t) &_kernel_end;
KHEAPBM kheap;
char *ptr;
void kernel_main()
{
init_gdt();
terminal_initialize();
init_idt();
kheapinit(&kheap);
kaddblock(&kheap, vaddr, 0x100000, 16);
printf("Cotton Candy OS\n");
printf("WIP\n");
breakpoint;
printf("ISRs installed and working.\n");
ptr = (char*)kmalloc(&kheap, 256);
printf("%s\n", ptr);
kfree(&kheap, ptr);
while (1) {}
}
Code: Select all
#include <stdint.h>
#include <stddef.h>
#include <kernel/string.h>
#include <kernel/stdio.h>
#include <kernel/mem.h>
void kheapinit(KHEAPBM *heap) {
heap->fblock = 0;
}
int kaddblock(KHEAPBM *heap, uintptr_t addr, uint32_t size, uint32_t bsize) {
KHEAPBLOCKBM *b;
uint32_t bcnt;
uint32_t x;
uint8_t *bm;
b = (KHEAPBLOCKBM*)addr;
b->size = size - sizeof(KHEAPBLOCKBM);
b->bsize = bsize;
b->next = heap->fblock;
heap->fblock = b;
bcnt = b->size / b->bsize;
bm = (uint8_t*)&b[1];
/* clear bitmap */
for (x = 0; x < bcnt; ++x) {
bm[x] = 0;
}
/* reserve room for bitmap */
bcnt = (bcnt / bsize) * bsize < bcnt ? bcnt / bsize + 1 : bcnt / bsize;
for (x = 0; x < bcnt; ++x) {
bm[x] = 5;
}
b->lfb = bcnt - 1;
b->used = bcnt;
return 1;
}
static uint8_t k_heapBMGetNID(uint8_t a, uint8_t b) {
uint8_t c;
for (c = a + 1; c == b || c == 0; ++c);
return c;
}
void *kmalloc(KHEAPBM *heap, uint32_t size) {
KHEAPBLOCKBM *b;
uint8_t *bm;
uint32_t bcnt;
uint32_t x, y, z;
uint32_t bneed;
uint8_t nid;
/* iterate blocks */
for (b = heap->fblock; b; b = b->next) {
/* check if block has enough room */
if (b->size - (b->used * b->bsize) >= size) {
bcnt = b->size / b->bsize;
bneed = (size / b->bsize) * b->bsize < size ? size / b->bsize + 1 : size / b->bsize;
bm = (uint8_t*)&b[1];
for (x = (b->lfb + 1 >= bcnt ? 0 : b->lfb + 1); x < b->lfb; ++x) {
/* just wrap around */
if (x >= bcnt) {
x = 0;
}
if (bm[x] == 0) {
/* count free blocks */
for (y = 0; bm[x + y] == 0 && y < bneed && (x + y) < bcnt; ++y);
/* we have enough, now allocate them */
if (y == bneed) {
/* find ID that does not match left or right */
nid = k_heapBMGetNID(bm[x - 1], bm[x + y]);
/* allocate by setting id */
for (z = 0; z < y; ++z) {
bm[x + z] = nid;
}
/* optimization */
b->lfb = (x + bneed) - 2;
/* count used blocks NOT bytes */
b->used += y;
return (void*)(x * b->bsize + (uintptr_t)&b[1]);
}
/* x will be incremented by one ONCE more in our FOR loop */
x += (y - 1);
continue;
}
}
}
}
return 0;
}
void kfree(KHEAPBM *heap, void *ptr) {
KHEAPBLOCKBM *b;
uintptr_t ptroff;
uint32_t bi, x;
uint8_t *bm;
uint8_t id;
uint32_t max;
for (b = heap->fblock; b; b = b->next) {
if ((uintptr_t)ptr > (uintptr_t)b && (uintptr_t)ptr < (uintptr_t)b + sizeof(KHEAPBLOCKBM) + b->size) {
/* found block */
ptroff = (uintptr_t)ptr - (uintptr_t)&b[1]; /* get offset to get block */
/* block offset in BM */
bi = ptroff / b->bsize;
/* .. */
bm = (uint8_t*)&b[1];
/* clear allocation */
id = bm[bi];
/* oddly.. GCC did not optimize this */
max = b->size / b->bsize;
for (x = bi; bm[x] == id && x < max; ++x) {
bm[x] = 0;
}
/* update free block count */
b->used -= x - bi;
return;
}
}
/* this error needs to be raised or reported somehow */
return;
}