no more PF in kmain, but still PF in process OR corruption of fb
This commit is contained in:
@@ -23,40 +23,36 @@ static uintptr_t end;
|
||||
// Kernel root table (level 4)
|
||||
extern uint64_t *kernel_pml4;
|
||||
|
||||
static void kheap_grow(size_t size)
|
||||
{
|
||||
size_t pages = ALIGN_UP(size + sizeof(struct heap_block_t), PAGE_SIZE) / PAGE_SIZE;
|
||||
|
||||
if (pages == 0) pages = 1;
|
||||
|
||||
for (size_t i = 0; i < pages; i++)
|
||||
{
|
||||
kheap_map_page();
|
||||
}
|
||||
}
|
||||
|
||||
void kheap_map_page()
|
||||
{
|
||||
uintptr_t phys = pmm_alloc();
|
||||
paging_map_page(kernel_pml4, end, phys, PTE_PRESENT | PTE_WRITABLE | PTE_NOEXEC);
|
||||
end += PAGE_SIZE;
|
||||
//DEBUG("Mapped first kheap page");
|
||||
}
|
||||
|
||||
void kheap_init()
|
||||
{
|
||||
kheap_start = ALIGN_UP(kernel_virt_base + KERNEL_SIZE, PAGE_SIZE);
|
||||
end = kheap_start;
|
||||
|
||||
size_t heap_pages = ALIGN_UP(KHEAP_SIZE, PAGE_SIZE) / PAGE_SIZE;
|
||||
DEBUG("Mapping %d kernel heap pages at 0x%p", heap_pages, kheap_start);
|
||||
|
||||
// At least 1 page must be mapped for it to work
|
||||
kheap_map_page();
|
||||
uintptr_t current_addr = kheap_start;
|
||||
|
||||
// Map/alloc enough pages for heap (KHEAP_SIZE)
|
||||
for (size_t i=0; i<heap_pages; i++)
|
||||
{
|
||||
uintptr_t phys = pmm_alloc();
|
||||
if (phys == 0)
|
||||
{
|
||||
panic(NULL, "Not enough memory available to initialize kernel heap.");
|
||||
}
|
||||
|
||||
paging_map_page(kernel_pml4, current_addr, phys, PTE_PRESENT | PTE_WRITABLE);
|
||||
current_addr += PAGE_SIZE;
|
||||
}
|
||||
|
||||
end = current_addr;
|
||||
|
||||
// Give linked list head its properties
|
||||
head = (struct heap_block_t*)kheap_start;
|
||||
head->size = PAGE_SIZE - sizeof(struct heap_block_t);
|
||||
head->size = (end-kheap_start) - sizeof(struct heap_block_t);
|
||||
head->free = true;
|
||||
head->next = NULL;
|
||||
DEBUG("kernel heap initialized, head=0x%p, max_size=%u bytes", head, KHEAP_SIZE);
|
||||
DEBUG("Kernel heap initialized, head=0x%p, size=%u bytes", head, head->size);
|
||||
}
|
||||
|
||||
void* kmalloc(size_t size)
|
||||
@@ -73,12 +69,12 @@ void* kmalloc(size_t size)
|
||||
if (curr->free && curr->size >= size)
|
||||
{
|
||||
// We split the block if it is big enough
|
||||
if (curr->size >= size + BLOCK_MIN_SIZE)
|
||||
if (curr->size >= size + sizeof(struct heap_block_t) + 16)
|
||||
{
|
||||
//struct heap_block_t* new_block = (struct heap_block_t*)((uintptr_t)curr + sizeof(struct heap_block_t) + size);
|
||||
struct heap_block_t* split = (struct heap_block_t*)((uintptr_t)curr + sizeof(*curr) + size);
|
||||
struct heap_block_t* split = (struct heap_block_t*)((uintptr_t)curr + sizeof(struct heap_block_t) + size);
|
||||
|
||||
split->size = curr->size - size - sizeof(*curr);
|
||||
split->size = curr->size - size - sizeof(struct heap_block_t);
|
||||
split->free = true;
|
||||
split->next = curr->next;
|
||||
|
||||
@@ -94,25 +90,12 @@ void* kmalloc(size_t size)
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
// If we're here it means we didn't have enough memory
|
||||
// for the block allocation. So we will allocate more..
|
||||
uintptr_t old_end = end;
|
||||
kheap_grow(size + sizeof(struct heap_block_t));
|
||||
|
||||
struct heap_block_t* block = (struct heap_block_t*)old_end;
|
||||
block->size = ALIGN_UP(end - old_end - sizeof(struct heap_block_t), 16);
|
||||
block->free = true;
|
||||
block->next = NULL;
|
||||
|
||||
// Put the block at the end of the list
|
||||
curr = head;
|
||||
while (curr->next)
|
||||
{
|
||||
curr = curr->next;
|
||||
}
|
||||
curr->next = block;
|
||||
|
||||
return kmalloc(size);
|
||||
// No growing. If we're here it means the initial pool
|
||||
// wasn't sufficient. Too bad.
|
||||
DEBUG("Kernel heap is OUT OF MEMORY!");
|
||||
// if we were terrorists maybe we should panic
|
||||
// or just wait for others to free stuff?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void kfree(void* ptr)
|
||||
|
||||
Reference in New Issue
Block a user