0

我正在尝试创建非常简单的 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 $在跳远之前做一个,它可以工作,程序会正确停止,但是当跳远完成时,它会重新启动机器。

我是不是忘了设置一个段或类似的东西?

4

1 回答 1

2

As your comment says, you need the linear address of GDT. You don't seem to have specified any ORG directive, so the assembler will use a base address of 0, and that won't match the address at runtime.

Also, not sure how you load the code at 0x100, the boot sector is normally loaded at 0x7c00.

The solution could be as simple as specifying ORG 0x7c00 at the top of your file.

于 2013-10-11T16:55:12.330 回答