/*
* Build early 4G boot pagetable
*/
/* Initialize Page tables to 0 */
leal pgtable(%ebx), %edi
xorl %eax, %eax
movl $((4096*6)/4), %ecx
rep stosl
/* Build Level 4 */
leal pgtable + 0(%ebx), %edi //edi是地址
leal 0x1007 (%edi), %eax //eax是内容, 内容是PDPTE的地址
movl %eax, 0(%edi)
/* Build Level 3 */
leal pgtable + 0x1000(%ebx), %edi
leal 0x1007(%edi), %eax
movl $4, %ecx // 需要4个表项
1: movl %eax, 0x00(%edi)
addl $0x00001000, %eax
addl $8, %edi
decl %ecx
jnz 1b
/* Build Level 2 */
leal pgtable + 0x2000(%ebx), %edi
movl $0x00000183, %eax
movl $2048, %ecx // 2048/(2^9) == 4 一共4个页面, 1个PDE页面占用512==(2^9)
1: movl %eax, 0(%edi)
addl $0x00200000, %eax
addl $8, %edi // 每个表项8个字节
decl %ecx
jnz 1b
/* Enable the boot page tables */
leal pgtable(%ebx), %eax
movl %eax, %cr3
/*
* Space for page tables (not in .bss so not zeroed)
*/
.section ".pgtable","a",@nobits
.balign 4096
pgtable:
/* 6个页面的原因是4G内存,
* 占用1个PML4E表项(1个页面)
* 占用4个PDPTE表项(1个页面)
* 占用4个PDE页面
* 1+1+4==6
*/
.fill 6*4096, 1, 0
如下图所示
CR3--------------
|
PML4E |
-------------<---
| |------------
| | |
| | | PML4E占用1个页面, 第一个表项8个字节, 指向第一个PDPTE页面
| | |
|... ... | |
-------------<----------
| |------------ PDPTE占用1个页面, 第一个表项8个字节, 指向第一个PDE页面
------------- |
| |-----------|----PDPTE第二个表项8个字节, 指向第一个PDE页面
------------- | |
| |-----------|---|----
------------- | | |
| |-----------|---|---|---
------------- | | | |
|... ... | | | | |
-------------<----------- | | |
| | | | |
| | | | |
| | | | |
| | | | |
|... ... | | | |
-------------<--------------- | |
| | | |
| | | |
| | | |
| | | |
|... ... | | |
-------------<------------------- |
| | |
| | |
| | |
| | |
|... ... | |
-------------<----------------------
| |
| |
| |
| |
|... ... |
-------------
内核页表成长记
https://blog.csdn.net/RichardYSteven/article/details/60584339
混沌初开--内核启动笔记
https://blog.csdn.net/richardysteven/article/details/52629731
linux临时页表初始化
https://blog.csdn.net/baidu_24256693/article/details/69056090
第一次启动分页管理
https://blog.csdn.net/yunsongice/article/details/6110676