Another Long Mode Paging Question
Posted: Thu Apr 15, 2010 12:05 pm
So I've been toying with the self mapping trick in long mode and have been having trouble with the 4 levels of indirection and keep it all straight in my head. From my understanding, if I self map the PML4 in its own last entry I'll end up with a mapping that looks like this:
The math is really easy for the PML4 stuff. I simply do: and I've got the address of the correct PML4 entry for that address. But it gets more confusing after that .
What is the correct bit-twiddling for PDPs, PDs and PTs? If I've done my math right, each PD represents 1GB of address space. So would that mean that the PD for address 0x40001000 (1GB + 1 Page) would be at the 513th entry aka:.
I think this is right, but it gets more confusing with PD and PDP entries.
Extending this, I might end up with this for the page table index:
But that yields addresses like PT addresses like 0xfffffffffffffff8 for 0xfffffffffffff000 which can't be right, since it is out side of the possible page ranges. I feel like the gap between kernel/user addresses (positive/negative) is what's messing up my math. Do I need to special case the upper half ones?
Could someone help clarify the proper way to formulate the different parts? Thanks.
Code: Select all
pml4_address = 0xfffffffffffff000;
pdp_address = 0xffffffffffe00000;
pd_address = 0xffffffffc0000000;
pt_address = 0xffffff8000000000;
Code: Select all
pml4_address + ((address >> 39) & 0x1ff)
What is the correct bit-twiddling for PDPs, PDs and PTs? If I've done my math right, each PD represents 1GB of address space. So would that mean that the PD for address 0x40001000 (1GB + 1 Page) would be at the 513th entry aka:
Code: Select all
0xffffff8000000000 + (512 * 8)
I think this is right, but it gets more confusing with PD and PDP entries.
Extending this, I might end up with this for the page table index:
Code: Select all
0xffffff8000000000 + (8 * (pt_offset + (pd_offset << 9) + (pdp_offset << 18) + (pml4_offset << 27)))
But that yields addresses like PT addresses like 0xfffffffffffffff8 for 0xfffffffffffff000 which can't be right, since it is out side of the possible page ranges. I feel like the gap between kernel/user addresses (positive/negative) is what's messing up my math. Do I need to special case the upper half ones?
Could someone help clarify the proper way to formulate the different parts? Thanks.