Page 1 of 1

Paging: Mapping page directories to high memory?

Posted: Sat Sep 22, 2007 3:59 am
by pcmattman
I'm now at the stage where I need to be able to access all my paging structures in a uniform way when the physical addresses of the page directories and/or page tables may not be mapped into the address space.

From what I've read, I'm meant to map the page directory into high memory (0xFFFFF000), but I don't understand how the page table for the address of the page directory is mapped.

If anyone could point me towards some documentation about this concept or provide some basic pointers, it would be greatly appreciated.

Posted: Sat Sep 22, 2007 4:17 am
by JamesM
I have some code from my last kernel that does this. (my current one has all page tables in the kernel heap, so they're always in VM).

This is my code in vmcreate.c -- making a new virtual address space.

Code: Select all

dir[PAGE_PTABLES/1024] = (unsigned int)realdir | PAGE_PRESENT | PAGE_RW | PAGE_USER;
In your case, PAGE_PTABLES would be 0xFFFFF, realdir is the physical address of your page directory. dir is the virtual address of your page directory, so that you can write to it.

It's then used in mmap.c:

Code: Select all

/// Map <pre>page_addr</pre> to frame <pre>frame_addr</pre> in the current
/// virtual-memory space.
/// \param  page_addr   Address of page to map.
/// \param  frame_addr  Address of frame to map to.
void
mmap (unsigned int page_addr, unsigned int frame_addr)
{
        unsigned int    page = page_addr / 4096;

        // make table accessible
        unsigned int   *table = PAGE_PTABLES * 4096 + (page / 1024) * 4096;

        // if table is not allocated, next line will cause a page fault, and the handler will allocate.
        unsigned int   *ent = &table[page % 1024];

        *ent =
                ((unsigned int) frame_addr & PAGE_ADDRESS) | PAGE_RW | PAGE_USER |
                PAGE_PRESENT;

        //ent = (unsigned int *) (*ent & PAGE_ADDRESS);
        //__asm("invlpg %0" :: "m" (*ent));
        write_cr3 (read_cr3 ());        // invalidate entire TLB - TODO fix to use invlpg properly!

        unsigned int    add = table[page % 1024];

}
Wow, i actually put meaningful comments in that file. That's useful!

Hope this helps.

EDIT: I'm not sure what that last line "unsigned int add = ..." is there for. :S

Posted: Sat Sep 22, 2007 9:51 pm
by pcmattman
Thanks JamesM, that helped a lot.

I tried it by mapping using 0xFFFFF000 as my page directory and it worked perfectly.

Only problem I face now is some minor issues with page table mapping, but I'll get those figured out soon enough.