这个OSDEV身份映射如何用于PAE寻呼?

时间:2017-08-13 22:32:08

标签: memory mapping virtual paging osdev

我试图尽可能地了解这个OSDEV tutorial的内容。我按照建议阅读了AMD64程序员manaul(第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上做了什么。

1 个答案:

答案 0 :(得分:0)


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

代码使用ebx保留要写入下一页表条目的值。它将其初始化为3,以设置 present 可写位(位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 - 1 jnz .SetEntry。如果将ecx减1之后,如果ecx不为零,它将运行循环的另一次迭代。由于ecx在循环前已初始化为512,因此上述指令将重复512次。 / p>


由于第一个条目使用的物理地址为零,并且每个后续条目的物理地址都高4KB,每个条目映射的是4KB,并且其中有512个,因此此代码填充了虚拟地址0(包括端值)的页表条目到2MB(不包括)的条目,这些条目的身份映射到物理内存的前2MB。 “身份”映射是指对其进行映射,以便物理地址等于线性地址。长模式下的每个页表都映射2MB的地址空间。由于此代码填充了一个页面表,因此它映射了2MB。

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

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

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

除了您问题代码中显示的设置之外,用于设置身份映射的代码还需要设置上述页面。