我正在尝试以64位创建非常简单的操作系统。我首先尝试进入保护模式,但此时我失败了。
当我跳远到32位时,机器重新启动。
我的代码被加载到内存中,另一个汇编程序位于地址0x100。
代码是用nasm编译的,我使用qemu -fda
运行程序。
这是我到目前为止的代码:
[BITS 16]
jmp _start
_start:
cli
lgdt [GDT64]
; Switch to protected mode
mov eax, cr0
or al, 1b
mov cr0, eax
; Desactivate pagination
mov eax, cr0
and eax, 01111111111111111111111111111111b
mov cr0, eax
jmp (CODE_SELECTOR-GDT64):pm_start
[BITS 32]
pm_start:
jmp $
GDT64:
NULL_SELECTOR:
dw GDT_LENGTH ; limit of GDT
dw GDT64 ; linear address of GDT
dd 0x0
CODE_SELECTOR: ; 32-bit code selector (ring 0)
dw 0x0FFFF
db 0x0, 0x0, 0x0
db 10011010b
db 11001111b
db 0x0
DATA_SELECTOR: ; flat data selector (ring 0)
dw 0x0FFFF
db 0x0, 0x0, 0x0
db 10010010b
db 10001111b
db 0x0
LONG_SELECTOR: ; 64-bit code selector (ring 0)
dw 0x0FFFF
db 0x0, 0x0, 0x0
db 10011010b ;
db 10101111b
db 0x0
GDT_LENGTH:
如果我在跳远之前做jmp $
,它可以正常停止,但是当跳远完成后,它会重新启动机器。
我是否忘记设置类似片段之类的内容?
答案 0 :(得分:2)
正如您的评论所说,您需要GDT的线性地址。您似乎没有指定任何ORG
指令,因此汇编程序将使用基址0,并且在运行时不会匹配该地址。
另外,不确定如何在0x100
加载代码,引导扇区通常在0x7c00
加载。
解决方案可以像在文件顶部指定ORG 0x7c00
一样简单。