【问题标题】:How to set CR3 register while in long mode (64 bit)如何在长模式下设置 CR3 寄存器(64 位)
【发布时间】:2015-06-24 23:39:01
【问题描述】:

我正在处理我的操作系统项目。入门代码已经跳转到长模式并设置临时页表。我现在已经设置并填充了我自己的页表,并按照我需要的方式完成了内存映射。现在我需要在 CR3 寄存器中设置 PML4T 的物理地址。

238 void setcr3(void * addr){
239 uint64_t temp=(uint64_t)addr;
240
241   __asm__ ("movq %0, %%cr3;"::"b"(temp));
242 }

执行该指令时会崩溃。 GDB一步一步附上

0x0000000000000000 in ?? ()
(gdb) b setcr3
Breakpoint 1 at 0xffffffff80201205: file sys/paging.c, line 238.
(gdb) c
Continuing.

Breakpoint 1, setcr3 (addr=0x221000) at sys/paging.c:238
238     void setcr3(void * addr){
(gdb) si
241       __asm__ ("movq %0, %%cr3;"::"b"(temp));
(gdb) si
0xffffffff80201209      241       __asm__ ("movq %0, %%cr3;"::"b"(temp));
(gdb) si
242     }
(gdb) si
Remote connection closed
(gdb)
244 #define write_cr3(x) \
245 __asm__ __volatile__("movl %0,%%cr3": :"r" (x))


Error while compiling

sys/paging.c: Assembler messages:
sys/paging.c:271: Error: unsupported instruction `mov'

编辑:

printf("address in cr3 %x\n", (uint64_t)pml4t - 0xffffffff80200000 + physbase);
setcr3( (void *) ( (uint64_t)pml4t - 0xffffffff80200000 + physbase) );


line 1 prints:
address in cr3 221000

【问题讨论】:

  • 您忘记指定目标架构

标签: assembly operating-system x86-64 page-tables


【解决方案1】:

您忘记在故障处显示实际指令。我假设它是movq %rbx, %cr3。此外,您还忘记显示%rbx 的值(或任何源寄存器)。

也就是说,指令集参考列出了以下两种适用的故障条件:

  • 如果当前权限级别不为 0。
  • 如果尝试将 1 写入 CR3 中的任何保留位。

【讨论】:

  • 我写入寄存器的值为0x221000
  • 根据所列条件,这看起来是无害的。仔细检查它实际上不是更改的分页表禁止获取下一条指令。也可能是您的调试环境有问题。我可以写0x221000cr3。除非您可以发布完整的可运行代码,否则我认为我无能为力。
【解决方案2】:

asm ("movq %0, %%cr3;"::"b"(temp));

我建议使用“r”代替“b”,以便编译器负责移动值并在执行指令后恢复它。

asm volatile("movl %0,%%cr3": :"r" (x));

使用 movq 代替 movl。

setcr3( (void *) ( (uint64_t)pml4t - 0xffffffff80200000 + physbase) );

如果是第一次在内核中设置页表,只需从 pml4t 的虚拟地址中减去 0xffffffff80200000 即可将物理地址传递给 cr3 寄存器。无需添加 physbase。这是因为,您可能会在加载内核的 elf 部分后获取内存中的第一个可用地址。

最后,最好在asm块前加上volatile,这样编译器就不会优化指令了。另外,为避免类型转换,请直接使用下面的行而不是宏,看看会发生什么。

asm volatile("movq %[cr3_var], %%cr3;"::[cr3_var]"r"((uint64_t)pml4t));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-05
    • 2021-09-13
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 2017-01-03
    • 2019-04-21
    • 1970-01-01
    相关资源
    最近更新 更多