首页 > 解决方案 > g++ 尝试从内核访问 0x00 时生成未定义指令(ud2)

问题描述

我正在尝试编写一个小内核。此代码在禁用分页和中断的 32 位保护模式下执行。

正如标题所暗示的,当我尝试0x00从我的内核访问时,编译器会生成ud2(未定义的指令)导致三重错误。

这是我尝试访问时功能的反汇编0x00

void SetupX64Paging()
{
  100070:   31 c0                   xor    %eax,%eax
  100072:   8d b4 26 00 00 00 00    lea    0x0(%esi,%eiz,1),%esi
  100079:   8d b4 26 00 00 00 00    lea    0x0(%esi,%eiz,1),%esi
    // The paging directory will be at 0x00h
    uint64_t *pageDirBase = (uint64_t *)0x00;
    //uint64_t *pageDirBase = (uint64_t *)0x00007BFF;

    // clear area for 4 tables (16KB)
    for(uint64_t i = 0; i < 512 * 4; i++)
        pageDirBase[i] = 0;
  100080:   c7 00 00 00 00 00       movl   $0x0,(%eax)
  100086:   83 c0 04                add    $0x4,%eax
    for(uint64_t i = 0; i < 512 * 4; i++)
  100089:   3d 00 20 00 00          cmp    $0x2000,%eax
  10008e:   75 f0                   jne    100080 <_Z14SetupX64Pagingv+0x10>
    PDPT = (uint64_t *)PML4 + 0x1000;  // 4KB
    PDT  = (uint64_t *)PML4 + 0x2000;  // 8KB
    PT   = (uint64_t *)PML4 + 0x3000;  // 12KB

    // Map each table entry into its parent and set the r/w and present flags
    PML4[0] = (uint64_t)PDPT | 0x3;
  100090:   c7 05 00 00 00 00 00    movl   $0x0,0x0
  100097:   00 00 00 
  10009a:   0f 0b                   ud2    
  10009c:   66 90                   xchg   %ax,%ax
  10009e:   66 90                   xchg   %ax,%ax

虽然它没有在反汇编中显示,但PML4被初始化为pageDirBase 在这个设置中,内核刚刚跳转到保护模式。中断被禁用,分页被禁用。

此文件中的代码编译为:

i686-elf-g++ -c Paging.cpp -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti -g -I../Common -I../Include                                  

是否有一个编译器指令应该用于使编译器不生成未定义的指令。

需要注意的一件特别的事情是,将内存清零的循环%eip = 100080工作得很好

标签: c++gccg++osdev

解决方案


推荐阅读