Page Fault when Cloning Page Directory

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
User avatar
Marionumber1
Member
Member
Posts: 56
Joined: Sun May 08, 2011 9:03 am

Page Fault when Cloning Page Directory

Post by Marionumber1 »

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");
}
Programmer and security enthusiast
DarkSide OS Kernel

Those who do not understand Windows NT are doomed to criticize it, poorly.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Page Fault when Cloning Page Directory

Post by Combuster »

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.
That's quite a wild thought leap. Is the fault address pointing to an interrupt handler or to the switch_page_directory?

Also, try running bochs' debugger and ask for "info tab" at the instructions after the move to cr3, to see what's actually in there and if that's what you expect.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Marionumber1
Member
Member
Posts: 56
Joined: Sun May 08, 2011 9:03 am

Re: Page Fault when Cloning Page Directory

Post by Marionumber1 »

Yes, I remember now that the triple fault occurred in switch_page_directory. So it's more likely that it just occurred after enabling paging, when it tried to fetch the next instruction.
Programmer and security enthusiast
DarkSide OS Kernel

Those who do not understand Windows NT are doomed to criticize it, poorly.
Post Reply