1

所以我遇到了一个问题,我现在似乎已经陷入了永恒,大约 3 天没有睡觉,现在试图自己解决这个问题,这对我来说有点令人沮丧,因为我觉得它应该老实说加载一个简单的表并执行远跳转到 32 位模式和繁荣是一项相对简单的任务!让它与我的数字快照一起工作。问题是每次我加载 GDT 并执行远跳时,我的计算机都会重新启动,正如我在许多其他帖子和处理相同问题的人中看到的那样。我使用'INT 0x13,AX = 0x20A'和'ES:BX = 0x1000:0'从我的引导加载程序加载。就在“CLI LGDT [GDT_END]”指令之前,如果我执行“JMP $”指令,它将成功打印有关已将其发送到内核的字符串。然而,

关于我可能做错的任何建议肯定会很可爱!花了几天时间,我似乎无法在任何地方找到并回答解决我的问题,尽管大量帖子似乎与同一个问题相似。这是我一遍又一遍地输入的内核代码,可能已经有几千次了……我试着让它看起来尽可能清晰,并尝试了所有我能找到的似乎对其他人有帮助的解决方案。这似乎是我最后的手段.. 如果需要引导加载程序,我也可以发布它,但是,就像我说的那样,它确实会在段:0x1000 偏移量:0 处加载到内核中。我通常从不使用 ORG,老实说不知道实际在做什么或正在做什么,我也找不到关于它的明确解释,但是无论有没有它,无论哪种方式,它都行不通。

    BITS 16
    ORG 0x10000
    JMP FLOW_KERNEL_START
    NOP

;----------------------------
;  GLOBAL DESCRIPTOR TABLE
;----------------------------
GDT_START:
    dq 0

GDT_CODE_SEGMENT:
    dw 0xFFFF
    dw 0
    db 0
    db 10011010b
    db 11001111b
    db 0

GDT_DATA_SEGMENT:
    dw 0xFFFF
    dw 0
    db 0
    db 10010010b
    db 11001111b
    db 0

GDT_END:
    dw GDT_END - GDT_START - 1
    dd GDT_START

;----------------------------
;       INCLUDES
;----------------------------
;%INCLUDE 'BIO_Land\gdt.asm'
;----------------------------

FLOW_KERNEL_START:
            ; SET SEGMENTS AND BOOT DEVICE VARIABLES
    XOR AX, AX
    CLI
    MOV SS, AX
    MOV SP, 0x9000
    STI

    MOV AX, 0x1000
    MOV DS, AX
    MOV ES, AX
    MOV FS, AX
    MOV GS, AX
    MOV byte [VAR_BOOTDEV], DL
    CALL FUNC_GOOD
    MOV AX, 0
    INT 0x16

            ; LOAD GDT TABLE AND MASK 32-BIT PROTECTED MODE FLAG
    CLI
    LGDT [GDT_END]
    MOV EAX, 0x10
    MOV DS, EAX
    MOV ES, EAX
    MOV FS, EAX
    MOV GS, EAX
    MOV SS, EAX
    MOV EAX, CR0
    OR EAX, 1
    MOV CR0, EAX
    JMP dword 0x8:FLOW_PROTECTED_MODE
    NOP

BITS 32
FLOW_PROTECTED_MODE:
    STI
    MOV byte [0xB8000], 'O'
    MOV byte [0xB8001], 0x0F
    MOV byte [0xB8002], 'O'
    MOV byte [0xB8003], 0x0F
    MOV byte [0xB8004], 'O'
    MOV byte [0xB8005], 0x0F
    MOV byte [0xB8006], 'O'
    MOV byte [0xB8007], 0x0F
    MOV byte [0xB8008], 'O'
    MOV byte [0xB8009], 0x0F
    JMP $

;----------------------------
;       FUNCTIONS
;----------------------------
FUNC_GOOD:
    MOV SI, VAR_STRING
    CALL FUNC_PRINT
    RET

FUNC_PRINT:
    MOV AH, 0x0E
    FUNC_PRINT_LOOP:
        LODSB
        CMP AL, 0
        JE FUNC_PRINT_DONE
        INT 0x10
        JMP FUNC_PRINT_LOOP
    FUNC_PRINT_DONE:
        RET
;----------------------------
;       VARIABLES
;----------------------------
VAR_BOOTDEV db 0

;----------------------------
;       STRINGS
;----------------------------
VAR_STRING db 'Hello world! You made it to the kernel!', 0

编辑:我已将 JMP $ 更改为 INT 0x16 以使事情更简单。如前所述,它可以正常启动,但是在按键上是重新启动。我已将 ORG 更改为 0x1000 和 0x10000。我不确定如何在地址 0x7C00 加载而不将其附加到引导加载程序本身内部,但话虽如此,我也尝试在引导加载程序的末尾放置一个缓冲区标签并在其中加载内核,假设地址在引导加载程序为 0x7E00 并将其用作 ORG 之后。我也尝试过完全省略 ORG(因为它已经通过 DS 设置,不是吗?),然后将 0x8:FLOW_PROTECTED_MODE 更改为 0x8:FLOW_PROTECTED_MODE+0x10000。我还尝试过使用 JMP 0x8:$$+$ 以及其他许多东西。BOSHC 说的正是我所期望的 JMPF 0x8:0x00001065 无法解析。我假设内核实际上是在内存中的某个地方加载的,因为它确实说 Hello world!,但我一生都无法弄清楚如何正确找到该位置或问题是什么。

4

0 回答 0