Paging 64bit: Recursive address calculation for 4k/2Mb pages
Posted: Sun May 16, 2021 4:23 am
Hi all,
i started to implement the recursive access to Page dirs in my OS, i created some macros etc.
And my understanding was that i have to build a special address to access recursively paging data structures.
That is fine, so first thing that i did was map pml4 entry into itself:
I used entry 510 because 511 is used for kernel in higher half.
And then from here depending on how i build the address i can access p4, p3, p2 p1.
But what i thought: ok if i'm using 2mb pages i need to build a 2mb type of virtual address that is:
So i created this macro:
But when using this address i see wrong information, for example if i build the address:
And try to print the content i see the value of first entry of p3 table not p4, and if i try to use this address:
The entry is from table p2, it honestly took me a while to figure out why, i had to read couple of times documentation on intel manuals to start to think what could have been the problem, and looks like it is that:
The address translation mechanism in ia32e is still:
Like when using 4kb pages, but when it reaches a 2mb page if the huge bit is set, it stops there, instead of resolving the pagetable, and while using the recursion the address to access data structures has to be built still like i'm accessing a 4kb page not a 2mb one, because there is no way that the pml4 entry has the hugepage bit set.
When i changed the function to use also the ptable:
I got the expected values.
I just wanted to know with this post few things:
1. If my reasoning is correct, and this is the expeceted behaviour, or it works in a different way, and i got expected values just by chance.
2. This means that i can have 4kb and 2mb pages coexisting at the same time?
3. But if this is the behaviour: if need to access a p2 entry in theory that can be a 4kb or 2mb page so in theory trhe OS should check the huege page bit before trying to access the page table from there (i say in theory because if the OS is stick only to one size, it should be safe in this case to make an assumption on the value of this bit)
i started to implement the recursive access to Page dirs in my OS, i created some macros etc.
And my understanding was that i have to build a special address to access recursively paging data structures.
That is fine, so first thing that i did was map pml4 entry into itself:
Code: Select all
mov eax, p4_table - KERNEL_VIRTUAL_ADDR ; Mapping the PML4 into itself
or eax, PRESENT_BIT | WRITE_BIT
mov dword [(p4_table - KERNEL_VIRTUAL_ADDR) + 510 * 8], eax
And then from here depending on how i build the address i can access p4, p3, p2 p1.
But what i thought: ok if i'm using 2mb pages i need to build a 2mb type of virtual address that is:
Code: Select all
| 63 .... 48 Sgn Ext | 47 ... 39 P4 | 38 ... 32 31 30 P3 | 29 .. 21 P2 | 20 ... 0 Offset |
Code: Select all
#define ENTRIES_TO_ADDRESS(pml4, pdpr, pd)((pml4 << 39) | (pdpr << 30) | (pd << 21))
Code: Select all
table = SIGN_EXTENSION | ENTRIES_TO_ADDRESS(510l,510l,510l)
Code: Select all
table = SIGN_EXTENSION | ENTRIES_TO_ADDRESS(510l,510l,0l)
The address translation mechanism in ia32e is still:
Code: Select all
| 63 .... 48 Sgn Ext | 47 ... 39 P4 | 38 ... 32 31 30 P3 | 29 .. 21 P2 | 20 12 Pt | 11... 0 Offset |
When i changed the function to use also the ptable:
Code: Select all
#define ENTRIES_TO_ADDRESS(pml4, pdpr, pd, pt)((pml4 << 39) | (pdpr << 30) | (pd << 21)) | (pt << 12)
I just wanted to know with this post few things:
1. If my reasoning is correct, and this is the expeceted behaviour, or it works in a different way, and i got expected values just by chance.
2. This means that i can have 4kb and 2mb pages coexisting at the same time?
3. But if this is the behaviour: if need to access a p2 entry in theory that can be a 4kb or 2mb page so in theory trhe OS should check the huege page bit before trying to access the page table from there (i say in theory because if the OS is stick only to one size, it should be safe in this case to make an assumption on the value of this bit)