此 OSDEV 身份映射如何用于 PAE 分页?



我正在尽我所能地理解这个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         ; 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,但除此之外,我看不出他对 ID 映射 2 MB 做了什么。


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

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


mov ecx, 512                 ; Set the C-register to 512.

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


.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.

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


add edi, 8                   ; Add eight to the destination index.

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


loop .SetEntry               ; Set the next entry.

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

由于第一个条目使用物理地址零,并且每个

后续条目的物理地址高 4KB,并且每个条目映射 4KB,并且有 512 个,因此此代码使用标识映射前 2MB 物理内存的条目填充虚拟地址 0(含(到 2MB(独占(的页表条目。"身份"映射意味着映射它,使物理地址等于线性地址。长模式下的每个页表映射 2MB 的地址空间。由于此代码填充一个页表,因此它映射 2MB。

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

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

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

设置标识映射的代码除了问题中的代码中显示的设置外,还需要设置上述页面。

最新更新