Memory Manager

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Memory Manager

Post by zap8600 »

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:

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) {}
}
Here is my memory code:

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;
}
Any help would be greatly appreciated.
thewrongchristian
Member
Member
Posts: 426
Joined: Tue Apr 03, 2018 2:44 am

Re: Memory Manager

Post by thewrongchristian »

zap8600 wrote: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:
[snip]
Any help would be greatly appreciated.
You're unlikely to get help with so little specific information.

The code you've posted has literally no paging code included. Why would you not expect a page fault if you've mapped no pages?

My kernel gets loads of page faults. My kernel handles them. Page faults are normal.
Post Reply