Memory 这个OSDEV标识映射如何用于PAE分页?

Memory 这个OSDEV标识映射如何用于PAE分页?,memory,mapping,virtual,paging,osdev,Memory,Mapping,Virtual,Paging,Osdev,我正在尽我所能去理解这是关于什么的。我已经按照建议阅读了AMD64程序员手册(第2卷)第4章和第5章,但我不明白当他经历这个循环时会发生什么: mov ebx, 0x00000003 ; Set the B-register to 0x00000003. mov ecx, 512 ; Set the C-register to 512. .SetEntry: mov DWORD [edi], ebx ;

我正在尽我所能去理解这是关于什么的。我已经按照建议阅读了AMD64程序员手册(第2卷)第4章和第5章,但我不明白当他经历这个循环时会发生什么:

    mov ebx, 0x00000003          ; Set the B-register to 0x00000003.
    mov ecx, 512                 ; Set the C-register to 512.

.SetEntry:
    mov DWORD [edi], ebx         ; Set the uint32_t at the destination index to the B-register.
    add ebx, 0x1000              ; Add 0x1000 to the B-register.
    add edi, 8                   ; Add eight to the destination index.
    loop .SetEntry               ; Set the next entry.
我明白他为什么把ebx设为3,但除此之外,我不知道他在做什么来映射2MB。


mov ebx, 0x00000003          ; Set the B-register to 0x00000003.
代码使用ebx保存要写入下一页表条目的值。它将其初始化为
3
,以设置当前位和可写位(位0和1)。从这里开始,它在每次循环迭代时向其添加
0x1000
,这不会影响这两个位。物理地址字段为零,因此这使得第一个条目映射到物理地址为零


循环运行512次迭代,每页表项一次迭代。每个条目为64位(8字节)。长模式下的一页表格可以容纳512个条目。512是4096/8


写一页表格条目


将要写入下一页表项的物理地址提前4KB。每个页面表条目映射4KB


将下一页表条目写入页表的下一条目。每个页表条目为8字节


循环指令意味着
ecx=ecx-1
jnz.SetEntry
。如果将
ecx
减少1后
ecx
不是零,它将运行循环的另一次迭代。由于在循环之前,
ecx
被初始化为512,这使得上述指令重复512次


由于第一个条目使用物理地址0,并且每个后续条目的物理地址更高4KB,每个条目映射4KB,其中有512个条目,因此此代码使用标识映射前2MB物理内存的条目填充虚拟地址0(包括)到2MB(排除)的页表条目。“标识”映射意味着将其映射为物理地址等于线性地址。长模式下的每个页表映射2MB的地址空间。由于此代码填充一页表,所以它映射2MB

请注意,仅此代码不足以设置分页。此代码仅填充页表条目。此代码适用于32位PAE分页或长模式分页

在PAE分页中,您还需要设置另外两个页面。对于长模式,您需要设置另外三个页面。PAE分页使用3级转换,其中顶层映射1GB区域,中层映射2MB区域,页表级映射4KB区域

长模式分页使用4级(或者在最新的处理器上,可以是5级)分页。在长模式下,顶层映射512GB区域,第二层映射1GB区域,第三层映射2MB区域,最外层映射4KB区域


设置标识映射的代码需要设置上述页面,以及问题代码中显示的设置。

此时,代码中的EDI指向内存地址0x4000处的页面表。共有512个页表条目,每个条目表示4kb,总共需要初始化2mb(512*4096)。循环通过每次迭代添加0x1000(4096=4kb)来设置物理地址页。它有效地将此页表(PT)映射到第一个2mb的物理ram。好的,谢谢。我不知道为什么我不能绕着它转。您认为这是一种在内核处理分页之前设置分页的好方法吗?如果您打算标识映射前2mb内存,那么它没有问题。如果您不打算在启用分页后保持标识映射,可以考虑使用。这简化了事情,因为您只需要一个页面目录指针表和一个页面目录。不需要循环。它也可以很容易地取消映射和失效。2mb分页对于许多用途来说可能不够小,但更方便的是临时更容易地对前2mb进行身份映射。我最后一次对2mb分页和PAE分页结构的评论适用于您处于32位保护模式的情况。是否有任何原因导致我犯三重错误?我的代码一直工作,直到我尝试切换到长模式。如果不是,我会犯三重错误吗?
mov ecx, 512                 ; Set the C-register to 512.
.SetEntry:
mov DWORD [edi], ebx         ; Set the uint32_t at the destination index to the B-register.
add ebx, 0x1000              ; Add 0x1000 to the B-register.
add edi, 8                   ; Add eight to the destination index.
loop .SetEntry               ; Set the next entry.