【问题标题】:How does this OSDEV Identity map work for PAE Paging?此 OSDEV 身份映射如何用于 PAE 寻呼?
【发布时间】:2018-01-21 18:10:08
【问题描述】:

我正在尽我所能了解OSDEV tutorial 的内容。我已按照建议阅读了 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 做了什么。

【问题讨论】:

  • 此时代码中的 EDI 指向位于内存地址 0x4000 的页表。有 512 个页表条目,每个条目代表 4kb,总共需要初始化 2mb (512*4096)。循环通过每次迭代添加 0x1000(4096=4kb) 来设置物理地址页。它有效地将此页表 (PT) 映射到物理内存的前 2mb。
  • 好的,谢谢。不知道为什么我无法解决这个问题。你会说这是在内核处理之前设置分页的好方法吗?
  • 如果你打算标识映射前 2mb 的内存没有问题。如果您不打算在启用分页后保留身份映射,则可以考虑使用 2MB paging rather than 4kb which is a feature of PAE 。这简化了事情,因为您只需要一个页面目录指针表和一个页面目录。不需要循环。它也可以很容易地被取消映射和失效。 2mb 分页对于很多用途来说可能不够小,但更方便地临时标识映射前 2mb。
  • 我上一条关于 2mb 分页和 PAE 分页结构的评论适用于您处于 32 位保护模式时。
  • 该教程有什么原因会导致我犯三重错误吗?我的代码一直有效,直到我尝试切换到长模式。如果不是,我会犯什么错?

标签: memory mapping virtual paging osdev


【解决方案1】:

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

代码使用 ebx 保存要写入下一个页表条目的值。它将其初始化为 3 以设置 presentwritable 位(位 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 减1 后ecx 不为零,它将运行循环的另一次迭代。由于ecx 在循环之前被初始化为512,这使得上述指令重复512 次。


由于第一个条目使用物理地址0,后续每个条目的物理地址高4KB,每个条目映射4KB,共有512个,这段代码填充虚拟地址0(含)的页表条目通过 2MB(独占)与标识映射前 2MB 物理内存的条目。 “身份”映射意味着将其映射为物理地址等于线性地址。长模式下的每个页表映射 2MB 的地址空间。由于此代码填充了一个页表,因此它映射了 2MB。

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 2010-11-21
    • 2011-05-13
    • 1970-01-01
    • 2012-05-30
    相关资源
    最近更新 更多