【问题标题】:Far jumping causes triple fault after PMode is enabled?PMode开启后跳远导致三重故障?
【发布时间】:2016-11-19 07:42:37
【问题描述】:

我的引导加载程序的这个阶段在0x7e0:0x0000 加载。经过一些“调试”后,我发现以下代码在我的远跳 之后会生成三重错误。如果我在跳转之前移动了挂起(是的,包括实际程序本身),它不会出现三重故障。抱歉,我不能包含更少的代码。我只是想确保我提供了足够的代码,以免遗漏错误。

这是我的代码:

bits 16

jmp SetUpPMode

GTDData:
    dd 0
    dd 0
    ;Code Descriptor
    dw 0xFFFF
    dw 0
    db 0
    db 10011010b
    db 11001111b
    db 0
    ;Data Descriptor
    dw 0xFFFF
    dw 0
    db 0
    db 10010010b
    db 11001111b
    db 0
GTDEnd:

GDTPointer:
    dw (GTDEnd - GTDData) - 1
    dd GTDData

LoadGDT:
    lgdt [GDTPointer]
    ret

SetUpPMode:
    cli
    mov ax, 0x7E0
    mov ds, ax

    call LoadGDT

    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp 0x8:main

bits 32

main:
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov esp, 0x90000

    jmp hang

hang:
    ;cli
    hlt
    jmp hang

我敢打赌,错误/错误非常明显,但我似乎无法找到它。有人可以指出吗? (如果重要的话,我正在使用 Virtual Box)

【问题讨论】:

  • 您应该在程序开始时使用一次 CLI,并且在设置适当的保护模式 IDT 之前不要使用 STI。将 PUSHA/POPA 放在 LGDT 周围也没有任何意义,因为它不会更改这些指令保存和恢复的任何寄存器。
  • @RossRidge 我清除了所有的stis 和clis,但它仍然是三重故障。我真的不认为你的评论是为了回答,但我想我不妨通知你。
  • 一个问题是您的代码中main 的偏移量与保护模式代码段中main 的偏移量不匹配。在您的代码中,它的偏移量类似于 0x00xx,但相对于保护模式代码段,它的偏移量将是 0x00007exx。您需要调整您的代码段库或程序的 ORG(例如,它在 0000:7e00 而不是 07e0:0000 加载)
  • @RossRidge 是的,这确实是问题所在。感谢您的提示和帮助。
  • 除了您提到的代码中的所有实际问题之外,我希望您启用 A20 行。

标签: assembly bootloader osdev


【解决方案1】:

您在0x07E0:0x0000 加载代码和数据。因此,汇编器和链接器所做的所有引用都基于0x07E0:0x0000 - 例如main,可能是0x0020 之类的。

但是您的 GDT 具有基于 0x00000000 的代码段 - 所以 jmp 0x8:mainJMP 到绝对地址 0x00000020 或其他东西 - 远不及代码在 0x00007E20 或任何地方的位置。要么更改 GDT 中段的基数,要么更改代码以从 0x0000 的实模式段工作。

【讨论】:

  • 我摆弄了org 和段,它停止了三重故障。问题已解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-13
  • 2021-02-28
  • 2013-04-15
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
  • 1970-01-01
相关资源
最近更新 更多