Page Fault when Cloning Page Directory
Posted: Sun Jan 27, 2013 7:53 pm
I was following Bran's Kernel Development Tutorial for a basic kernel, and once I finished it, I decided to integrate Paging, Heap, and Multitasking code from JamesM's tutorial. Everything went fine, until I got to the Multitasking code and tried to clone a page directory. When I try to load the address of the cloned directory into CR3, I get a Triple Fault. The Bochs debugger says that it tried to execute code on an unmapped page, which leads me to believe that the interrupt handlers don't get mapped correctly.
Code: Select all
page_directory_t *clone_directory(page_directory_t *src) {
unsigned int phys;
// Make a new page directory and obtain its physical address.
page_directory_t *dir = (page_directory_t*) kmalloc_ap(sizeof(page_directory_t), &phys);
// Ensure that it is blank.
memset(dir, 0, sizeof(page_directory_t));
// Get the offset of tablesPhysical from the start of the page_directory_t structure.
unsigned int offset = (unsigned int) dir->tablesPhysical - (unsigned int) dir;
// Then the physical address of dir->tablesPhysical is:
dir->physicalAddr = phys + offset;
// Go through each page table. If the page table is in the kernel directory, do not make a new copy.
unsigned int blank = 0;
unsigned int link = 0;
unsigned int copy = 0;
int i;
for (i = 0; i < 1024; i++)
{
if (!src->tables[i]) {
blank++;
continue;
}
if (src->tables[i] == kernel_directory->tables[i]) {
// It's in the kernel, so just use the same pointer.
dir->tables[i] = src->tables[i];
dir->tablesPhysical[i] = src->tablesPhysical[i];
link++;
} else {
// Copy the table.
unsigned int phys;
dir->tables[i] = clone_table(src->tables[i], &phys);
dir->tablesPhysical[i] = phys | 0x07;
copy++;
}
}
kprintf("Blank Page Tables: %d\nLinked Page Tables: %d\nCopied Page Tables: %d\n", blank, link, copy);
return dir;
}
Code: Select all
void switch_page_directory(page_directory_t *dir) {
__asm__ __volatile__ ("cli");
current_directory = dir;
asm volatile("mov %0, %%cr3":: "r"(dir->physicalAddr)); // Error happens here
unsigned int cr0;
asm volatile("mov %%cr0, %0" : "=r"(cr0));
cr0 |= 0x80000000; // Enable paging!
asm volatile("mov %0, %%cr0":: "r"(cr0));
__asm__ __volatile__ ("sti");
}