I have recently studied the IA32e paging, and though I know how that works, when I came across a real example, I can't understand what the value in each entry presents.
I have read the manual, which told me there are a few flag bits to be set, and I tried to break down the value of PML4E, PDPTE, and PDE in the following example into the format written on the manual, but the result seems to be wrong.
//======= init page
.align 8
.org 0x1000
__PML4E:
.quad 0x102007
.fill 255,8,0
.quad 0x102007
.fill 255,8,0
.org 0x2000
__PDPTE:
.quad 0x103003
.fill 511,8,0
.org 0x3000
__PDE:
.quad 0x000083
.quad 0x200083
.quad 0x400083
.quad 0x600083
.quad 0x800083
.quad 0xe0000083 /*0x a00000*/
.quad 0xe0200083
.quad 0xe0400083
.quad 0xe0600083 /*0x1000000*/
.quad 0xe0800083
.quad 0xe0a00083
.quad 0xe0c00083
.quad 0xe0e00083
.fill 499,8,0
The code comes from the book <<一個64位操作系統的設計與實現>> The Design and Implementation of a 64-bit OS . The code is available in this GitHub repository
The kernel are loaded at memory 0x100000;__PML4E, __PDPTE, and __PDE are stored at offset 0x1000, 0x2000, 0x3000 relative to where kernel is loaded
but what i can not understand is that why there is a 0x102007 instead of 0x102000, 0x103003 instead of 0x103000, and the intricate value in __PDE.
A PML4E with value 0x102007
is 0x102000 + FLAG_PRESENT + FLAG_WRITE + FLAG_USER
which sets the 512GiB region controlled by this entry to be writable and accessible to code with CPL > 0 (and mark the entry present).
A PDPTE with value 0x103003
is 0x102000 + FLAG_PRESENT + FLAG_WRITE
which sets the 1GiB region controlled by this entry to be writable but not accessible to code with CPL > 0 (and mark the entry present).
A PDE with value 0x000083
is 0x000000 + FLAG_PRESENT + FLAG_WRITE + FLAG_PAGESIZE
which makes the PDE directly map a writable 2MiB page that cannot be accessed by code with CPL > 0 (and mark the entry present).
Assuming paging is set up, these paging structures create the following memory map:
0 - 10MiB Identity mapped as writable for the kernel
10MiB - 26MiB Mapped to 0xe0000000 as writable for the kernel
26MiB - 1GiB Not mapped
1GiB - 512GiB Not mapped
512GiB - 64TiB Not mapped
64TiB - 64TiB + 512GiB Alias to range 0 - 512GiB
64TiB + 512GiB - 256TiB Not mapped
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.