【问题标题】:Jump to Protected Mode is restarting QEMU跳转到保护模式正在重新启动 QEMU
【发布时间】:2021-07-12 07:56:33
【问题描述】:

我已经成功编写了实模式代码。但问题始于 32 位保护模式。在跳转到保护模式之前,我已经使用 cli 禁用了中断使用 lgdt 加载 GDT在 cr0 中设置 32 位模式位。但是 QEMU 正在无限重启。以下是代码

boot.asm

[BITS 16]
            BOOTSEG equ 0x7c00
            DATASEG equ 0x07c0
            STACKSEG equ 0x17c0
            EXTRASEG equ 0x37c0
            STACKPOINT equ 0x0000

            BLACKONWHITE equ 0x0F
            YELLOWONBLUE equ 0x1E

            VIDEO_MEMORY equ 0xb8000

            global _start

_start:

            xor ax, ax

            mov ax, STACKSEG
            mov ss, ax              ;initializing stack segment
            mov sp, STACKPOINT
            
            mov ax, DATASEG
            mov ds, ax              ;initializing data segment

            mov ax, EXTRASEG
            mov es, ax               ;initializing extra segment

            call Switch_To_Pm

            %include "./screen.asm"
            %include "./lib.asm"
            %include "./gdt.asm"
            %include "./protected_mode/switch_to.asm"

[bits  32]

Begin_Pm:
            jmp $

            times 510 - ($ - $$) db 0

            dw 0xAA55

gdt.asm

gdt_start:

null_descriptor:
                dd 0x0
                dd 0x0

code_descriptor:
                dw 0xffff
                dw 0x0
                db 0x0
                db 10011010b
                db 11001111b
                db 0x0

data_descriptor:
                dw 0xffff
                dw 0x0
                db 0x0
                db 10010010b
                db 11001111b
                db 0x0

gdt_end:

gdt_descriptor:
                dw gdt_end - gdt_start - 1
                dd gdt_start

CODE_SEG equ code_descriptor - gdt_start

DATA_SEG equ data_descriptor - gdt_start

protected_mode/switch_to.asm

    [BITS 16]
Switch_To_Pm:
                cli
                lgdt [gdt_descriptor]
                mov eax , cr0
                or eax , 0x1
                mov cr0 ,eax
                jmp CODE_SEG:Init_Pm

[BITS 32]

Init_Pm:
                mov ax, DATA_SEG
                mov ds, ax
                mov ss, ax
                mov es, ax
                mov fs, ax
                mov gs, ax

                call Begin_Pm

lib.asm 包含一个使用 int 0x15 的延迟例程,screen.asm 包含在实模式下打印文本的 BIOS 例程。

以下是我用来构建的命令

nasm -fbin -o boot.bin boot.asm
qemu boot.bin

不知道为什么,但是 QEMU 正在无限重启。直到实模式的代码运行良好。切换到保护模式可能有问题。

感谢任何帮助

【问题讨论】:

  • 重启可能是三重故障。 Qemu 有办法记录所有故障吗?
  • 您可能希望在通话前加载 esp。我不确定 esp 的高位是否保证为零。
  • 你确定 Qemu 在 7c00 加载你的代码吗?
  • @prl 我做了 qemu boot.bin -D ./log.txt。但是 qemu 没有在文件中记录任何内容
  • 尝试使用以下选项运行 qemu:-d int -no-reboot -no-shutdown(和 -D,如果您想登录到文件)。这应该告诉您发生了哪些异常,并且它将在第一次三重故障后停止,而不是无休止地重新启动。

标签: assembly x86 nasm protected-mode


【解决方案1】:

我想我已经确定了问题所在。问题出在线路上 jmp CODE_SEG:Init_Pmprotected_mode/switch_to.asm。我应该为远跳添加一个 0x7c00 的偏移量。
相反,我使用[org 0x7c00] 并重写了实模式和保护模式代码,它起作用了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    • 2012-10-10
    • 2012-02-26
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多