跳转到保护模式正在重新启动 QEMU
Jump to Protected Mode is restarting QEMU
我已经成功编写了实模式代码。但麻烦始于 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 会无限重启。直到实模式的代码运行良好。可能切换到保护模式有问题。
事先感谢任何帮助
我想我已经找到问题所在了。问题出在线路上
jmp CODE_SEG:Init_Pm
在 protected_mode/switch_to.asm
中。我应该为远跳添加 0x7c00 的偏移量。
相反,我使用 [org 0x7c00]
并重写了实模式和保护模式代码,它起作用了。
我已经成功编写了实模式代码。但麻烦始于 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 会无限重启。直到实模式的代码运行良好。可能切换到保护模式有问题。
事先感谢任何帮助
我想我已经找到问题所在了。问题出在线路上
jmp CODE_SEG:Init_Pm
在 protected_mode/switch_to.asm
中。我应该为远跳添加 0x7c00 的偏移量。
相反,我使用 [org 0x7c00]
并重写了实模式和保护模式代码,它起作用了。