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.