Paging Enabled... Where's the Page Fault?

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
dega512
Posts: 4
Joined: Mon Jan 14, 2008 11:35 am

Paging Enabled... Where's the Page Fault?

Post by dega512 »

I've been trying to get paging to work for weeks now with no luck (triple fault after triple fault); after getting incredibly frustrated I finally decided to write some "simple" code to enable paging and identity map the first 4MB of memory to practice the theory and process behind enabling paging. After completing my little practice assignment I didn't get any triple faults, but my code to invoke a page fault well, just doesn't invoke a page fault. Here is my code:

Code: Select all

printf("Setting up paging.\n");

// typedef unsigned int u32;
// void *kpmalloc(u32 size, bool pageAligned);  // (placement malloc)
u32 **dir = (u32 **)kpmalloc(4096, TRUE);
u32 *table = (u32 *)kpmalloc(4096, TRUE);

memset(dir, 0, 4096);
memset(table, 0, 4096);

/* identity map the first 4MB of memory */

u32 i = 0;  // current page descriptor within the table
u32 addr = 0;  // current address
while (i < 1024)
{
    table[i] = addr | 3;  // RW + Supervisor + Present
    addr += 4096;
    i++;
}

// the first entry in the descriptor describes the virtual address for 0MB-4MB,
// so this is where our table must go
dir[0] = (u32 *)((u32)table | 3); // RW + Supervisor + Present

// put the page directory in cr3
asm volatile("mov %0, %%cr3":: "r"(dir));

// enable the paging bit in cr0
u32 cr0;
asm volatile("mov %%cr0, %0": "=r"(cr0));
cr0 |= 0x80000000; // Enable paging!
asm volatile("mov %0, %%cr0":: "r"(cr0));

// since we identity mapped the first 4 MB of memory,
// dereferencing a pointer pointing to the end of the first
// 5MB should invoke a page fault...
u32 fault = *(u32 *)(5 * 1024 * 1024);

printf("Test done...\n");
My output is simply:
Setting up paging.
Test done...
Something must be wrong with my theory and/or process, because my IDT #14 handler just isn't being called. I know the problem that I'm experiencing can't be that a page fault is occurring and my IDT handler isn't setup properly to handle it because the following code invokes my handler no problem.

Code: Select all

// test the page fault handler
asm volatile("int $14");
Any ideas as to where I screwed up or suggestions on more places to search would be greatly appreciated!

Thanks!

P.S. I'm using QEMU for emulation, but I highly doubt QEMU is behind my problem.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Hi,

Code: Select all

// since we identity mapped the first 4 MB of memory,
// dereferencing a pointer pointing to the end of the first
// 5MB should invoke a page fault...
u32 fault = *(u32 *)(5 * 1024 * 1024); 
Your compiler will remove this statement. The return value is not used anywhere, so it is not needed, technically.

To stop it getting removed, either mark your 'fault' variable as volatile, or (better), do a write to memory instead of a read. The compiler can't optimise out a write.

Cheers,

James
User avatar
dega512
Posts: 4
Joined: Mon Jan 14, 2008 11:35 am

Post by dega512 »

Hey it worked! I forgot I had the optimize option turned on :shock: .

Thanks a ton!
There is too much blood in my caffeine stream...
Post Reply