【问题标题】:Disabling Paging in x86 32bit在 x86 32 位中禁用分页
【发布时间】:2015-11-21 09:42:48
【问题描述】:

我正在尝试直接写入物理内存位置,所以我使用汇编函数首先禁用分页,写入值,然后重新启用分页,但由于某种原因,尝试时仍然会触发页面错误写入值。

据我了解,在 x86-32bit 中,通过翻转 cr0 中的第 32 位来打开和关闭分页,所以这是我的汇编函数:

mov 4(%esp), %ecx //address
mov 8(%esp), %edx //value

mov %cr0, %eax
and $0x7fffffff, %eax
mov %eax, %cr0

mov %edx, (%ecx) //this line still triggers a page fault somehow

or $0x80000000, %eax
mov %eax, %cr0

ret

这是实现我想做的正确方法吗?如果是这样,为什么在cr0中的位翻转时仍然会触发页面错误?

【问题讨论】:

  • 您是否尝试在已启用分页的操作系统上禁用分页?它是您自己的操作系统还是众所周知的操作系统(linux、Windows、MacOS)?当现代操作系统已经启用分页时,您绝对应该禁用分页。要写入物理地址,请使用操作系统提供的工具(/dev/memDevice\PhysicalMemory)或 kernel.BTW 提供的函数,看来(我不习惯 AT&T 语法)你反转了值代码中的地址。
  • 其实是第 31 位,因为第 0 位是第一位。
  • 如果代码从具有不同物理地址和虚拟地址的页面运行,禁用分页会不会导致错误?或者更确切地说,使一些其他指令运行,因为EIP 是一个物理地址。您是否在bochs 中单步执行了此操作,或者在遇到错误时确切了解发生了什么?
  • 另外,我认为 sane 的方法是将物理页面映射到某处的虚拟内存中,然后写入它。不过,那是无聊的方式。这种疯狂的方式看起来确实很有趣。
  • 如果代码、堆栈、GDT、IDT、所有中断处理程序以及它们可能使用的所有东西都是标识映射的,那么禁用和重新启用分页是“安全的”;但它也会很慢(使所有 TLB 条目无效),如果一切都是身份映射的,你必须想知道为什么你首先要启用分页.. ;-)

标签: assembly x86 paging virtual-memory page-fault


【解决方案1】:

当跳转指令(仅限远跳转?)完成时,CR0 寄存器中的更改将生效。

但是禁用分页并不是一个好主意:您必须保证代码位于 1:1 映射内存中并且中断被禁用。

如果您使用堆栈,您还必须确保堆栈是 1:1 映射的。

通过将ecx中的物理地址映射到虚拟地址然后写入虚拟地址的方式来修改页表要容易得多。

【讨论】:

    【解决方案2】:

    Intel 64 and IA-32 Architectures Software Developer's Manual System Programming Guide 描述了如何在从保护模式切换回实模式的过程中禁用分页:

    9.9.2 切换回实地址模式

    处理器从保护模式切换回实地址模式 如果软件清除 CR0 中的 PE 位 使用 MOV CR0 指令注册。重新进入的过程 实地址模式应执行以下步骤:

    1. 禁用中断。 CLI 指令禁用可屏蔽硬件中断。 NMI 中断可以通过外部电路禁用。
    2. 如果启用分页,请执行以下操作:

      • 将程序控制转移到标识映射到物理地址的线性地址(即线性 地址等于物理地址)。
      • 确保 GDT 和 IDT 位于身份映射页面中。
      • 清除CR0寄存器中的PG位。
      • 将 0H 移入 CR3 寄存器以刷新 TLB。

    您似乎错过了最后一步。 TLB(翻译后备缓冲区)是 CPU 缓存页表条目的地方,并且在清除 PG 位后仍然处于活动状态。需要清空TLB,否则CPU会继续使用。

    请注意,在再次设置 PG 位之前,您必须重新加载 CR3。此外,由于您所做的事情非常不寻常,您可能会遇到模拟器的错误和兼容性问题。它可能只能在切换回实模式的过程中正确处理禁用分页,因为这可能是唯一经过测试的场景。甚至物理 CPU 也可能在这方面存在问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-25
      • 2011-11-04
      • 2013-09-22
      • 1970-01-01
      • 2021-05-28
      • 2020-03-08
      • 1970-01-01
      • 2015-06-09
      相关资源
      最近更新 更多