I'm a first time poster and I'm still learning a lot so please be kind :)
I'm attempting to start adding multitasking into my kernel. At the moment, I am having a bug where it gets stuck in a boot loop after trying to change the page directory to the current_directory by moving into cr3.
This started out a little more originally, but after encountering the bug, I basically just copied the paging.c file from http://www.jamesmolloy.co.uk/tutorial_h ... sking.html to see if I was accidentally doing something wrong, but the error still persisted.
Does anyone know what the issue here is?
The functions in question:
Code: Select all
void initialize_paging() {
// The size of physical memory. For the moment we
// assume it is 16MB big.
u32 mem_end_page = 0x1000000;
nframes = mem_end_page / 0x1000;
frames = (u32*)kmalloc(INDEX_FROM_BIT(nframes));
memory_set(frames, 0, INDEX_FROM_BIT(nframes));
// Let's make a page directory.
//u32 phys;
kernel_directory = (page_directory_t*)kmalloc_a(sizeof(page_directory_t));
memory_set(kernel_directory, 0, sizeof(page_directory_t));
kernel_directory->physicalAddr = (u32)kernel_directory->tablesPhysical;
// Map some pages in the kernel heap area.
// Here we call get_page but not alloc_frame. This causes page_table_t's
// to be created where necessary. We can't allocate frames yet because they
// they need to be identity mapped first below, and yet we can't increase
// placement_addr between identity mapping and enabling the heap!
for (u32 i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += 0x1000)
get_page(i, 1, kernel_directory);
// We need to identity map (phys addr = virt addr) from
// 0x0 to the end of used memory, so we can access this
// transparently, as if paging wasn't enabled.
// NOTE that we use a while loop here deliberately.
// inside the loop body we actually change placement_addr
// by calling kmalloc(). A while loop causes this to be
// computed on-the-fly rather than once at the start.
// Allocate a lil' bit extra so the kernel heap can be
// initialised properly.
for (u32 i = 0; i < placement_addr + 0x1000; i += 0x1000) {
// Kernel code is readable but not writeable from userspace.
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
}
// Now allocate those pages we mapped earlier.
for (u32 i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += 0x1000)
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
// Before we enable paging, we must register our page fault handler.
register_interrupt_handler(14, page_fault);
// Now, enable paging!
switch_page_directory(kernel_directory);
// Initialise the kernel heap.
kheap = create_heap(KHEAP_START, KHEAP_START + KHEAP_INITIAL_SIZE, 0xCFFFF000, 0, 0);
serial_print("Cloning kernel_directory to current_directory...");
current_directory = clone_directory(kernel_directory);
serial_print("OK\n");
serial_print("Switching page directory to current_directory...");
switch_page_directory(current_directory);
serial_print("OK\n");
}
void switch_page_directory(page_directory_t* dir) {
current_directory = dir;
asm volatile("mov %0, %%cr3" ::"r"(dir->physicalAddr));
u32 cr0;
asm volatile("mov %%cr0, %0"
: "=r"(cr0));
cr0 |= 0x80000000; // Enable paging!
asm volatile("mov %0, %%cr0" ::"r"(cr0));
}
Thank you very much!