I have a nice physical allocator that seems to work fine. I have been using it in my kernel for at least 2 weeks without any issues.
Now, I would now like to setup paging in my kernel. I understand the theory, what it does and how it works. Now according to the wiki, I need my paging structures to be page-aligned. I dont really quite under stand what this means but I assume it means that the address is a multiple of 4096, please correct me if i am wrong.
Now I somehow would need to make my allocator be able to serve out page-aligned addresses, but I am not sure on the right way to do this.
Here is my allocator code, if you would like to take a peep:
Code: Select all
// kalloc.c
// Written by Harry Rigg
// Kernel memory allocator
#include <kernel/mem/kalloc.h>
void
kalloc_init(void* mmloc, unsigned long mmsize)
{
memory_map_entry_t* current_map = (memory_map_entry_t*) mmloc;
memzone_t* last_looped;
memzone_t* last_free;
size_t last_size;
int i=0;
while(current_map < mmloc + mmsize)
{
if(current_map->type == 1)
{
memzone_t* append;
append = (void*)current_map->base;
append->flags =0;
append->prev_h=last_looped;
last_looped->next_h = append;
last_looped = (void*) append;
last_free = (void*) append;
last_size = current_map->len;
i++;
}else{
memzone_t* append = (void*)current_map->base;
append->flags = 1;
append->prev_h = last_looped;
last_looped->next_h = append;
last_looped = (void*) append;
}
current_map = (memory_map_entry_t*) ((uint32_t)current_map + current_map->size + sizeof(uint32_t));
}
// Add a EOM (End Of Memory) header at the end of the free memory
memzone_t* eom = (void*) last_free + last_size - sizeof(memzone_t);
// Set the flags to EOM
eom->flags = 3;
eom->next_h =0;
eom->prev_h = last_free->prev_h;
last_free->next_h = eom;
return;
}
void*
kmalloc(size_t size)
{
memzone_t* this = (memzone_t*)0x0;
for(int i; 1; i++)
{
// Used?
if(this->flags==1){
this = (void*)this->next_h;
continue; // Already used
}
// End of memory?
if(this->flags==3)
{
break;
}
// Big enough?
if((this->next_h - (size_t)this) - sizeof(memzone_t) < size){
this = (void*)this->next_h;
continue; // Too small
}
// This area of memory suits our needs
// Create new header for the area left over
memzone_t* split = (void*)this + sizeof(memzone_t) + size;
split->flags = 0;
split->prev_h = (void*)this;
split->next_h = (void*)this->next_h;
// Adjust some of this headers properties
this->flags = 1;
this->next_h = split;
return (void*)this+sizeof(memzone_t);
}
return (void*)-1;
}
void*
kcalloc(size_t size)
{
void* ptr = kmalloc(size);
memset(ptr, 0, size);
return ptr;
}
void*
krealloc(void* ptr, size_t nsize)
{
void* nptr = kmalloc(nsize);
if(nptr == -1)
return (void*)-1;
memzone_t* fmz = (void*) ptr - sizeof(memzone_t);
size_t this_size = (fmz->next_h - (size_t)fmz) - sizeof(memzone_t);
memcpy(nptr, ptr, this_size);
kfree(ptr);
return nptr;
}
void
kfree(void* alloc)
{
memzone_t* this = (void*)alloc-sizeof(memzone_t);
memzone_t* next = (void*) this->next_h;
if(next->flags==1)
{
this->flags = 0;
return;
}
while(1)
{
next = (void*) next->next_h;
if(next->flags == 3)
break;
if(next->flags == 1)
break;
}
this->next_h = (void*)next;
this->flags = 0;
}
Should I check to see if a free header is page-aligned, and if it is not, do a bit of messing with sizes and pointers to make it page-aligned? Or would this be to slow.
I have a few ideas, I just dont know how I should do it.
Thanks in advance, Harry.
P.S. I dont want you to give me code or modify my code, I really want your ideas and theorys that I can build on
Also: If you notice any flaws in my allocator, spit em out at me