Page 1 of 1

Paging Questions (amd64)

Posted: Thu Nov 13, 2008 12:47 pm
by AndreaOrru
Hi all, excuse me for my (probably) bad english.

We (me and a friend of mine) are coding a 64-bit OS and for now we have implemented a bootloader (which setups basic identity paging, too), screen output functions, descriptors tables, software and hardware interrupts, some basic C library's functions and a physical memory manager.
The latest one uses a bitmap in order to keep track of the [un]used blocks (4096 bytes each).

Now I'm about to write the virtual memory manager, through paging. But I still have some doubts.

Considering that an amd64-compliant processor can address up to 256 TB of memory, I can't allocate space for all the paging structures in order to potentially map all of them, because it will take too much space, so I have to allocate and map them dinamically.
I already know the PML4 latest entry's trick, that allows me to access all the PML1 entries in the latest 512gb of virtual memory.
But obviously I can't setup all the paging structures from PML4 to PML2 in order to cover all the 256TB, so I need a way to access them too, once paging is activated.

Am I missing something? I will be very thankful if someone showes how he handles paging, and how physical and virtual memory management works together.

Re: Paging Questions (amd64)

Posted: Thu Nov 13, 2008 3:08 pm
by CodeCat
Rather than wanting to map them all from the start, just map them as needed. That way, you can create the mapping for an additional table as soon as it's created, and until it's needed you won't be wasting any space.

Re: Paging Questions (amd64)

Posted: Thu Nov 13, 2008 3:30 pm
by AndreaOrru
That's what I want to do.

But, for example:

- Map the kernel at 0xFFFF800000000000;
- Point the last PML4 entry to the PML4 table;
- Load the PML4;

What I can do now, in order to map 4kb starting from virtual address 0x0000000000000000, to whatever physical address?

I don't know where the paging structures are located in the virtual address space, except for the PML1 tables (they are in the latest 512GB thanks to the PML4's last entry trick).
To map at any virtual address, I have to set not only the PML1 tables, but also the corresponding PML4, 3, 2 tables. For that address, I have to point the first PML4 entry to a PML3 table, the first entry of this to a PML2 table, the first entry of this to a PML1 table, of which the first page have to point a physical address.

Again: am I missing something?

Re: Paging Questions (amd64)

Posted: Sat Nov 15, 2008 1:18 am
by thooot
You need to map an entry of the page map level 4 table, the page directory pointer table and the page directory table to the pml4 page. This will let you access all levels of the page table hierarchy using a fractal memory map.

Here's what my code looks like:

Code: Select all

    pml4 = (PageTable*) KeAllocatePage();
    pdp = (PageTable*) KeAllocatePage();
    pd = (PageTable*) KeAllocatePage();

    KeZeroPage(pml4);
    KeZeroPage(pdp);
    KeZeroPage(pd);

    // Set up the page table elements needed for fractal memory
    pml4->pages[510].raw = ((uint64) pdp) | 0x3;
    pdp->pages[510].raw = ((uint64) pd) | 0x3;

    // Set up fractal memory
    pml4->pages[511].raw = ((uint64) pml4) | 0x3;
    pdp->pages[511].raw = ((uint64) pml4) | 0x3;
    pd->pages[511].raw = ((uint64) pml4) | 0x3;
Using this, the page tables start at 0xFFFFFF8000000000.
The page directories start at 0xFFFFFF7FC0000000.
The page directory pointers start at 0xFFFFFF7FBFE00000.

And you can access all levels of the page table hierarchy directly.

Re: Paging Questions (amd64)

Posted: Sat Nov 15, 2008 7:43 am
by AndreaOrru
I've figured out exactly that, reasoning about it at school just this morning. Thank you very much anyway.