首页 > 解决方案 > 切换到 32 位保护模式后,引导扇区卡在 Qemu 中的“从硬盘引导”循环中

问题描述

使用 qemu 运行我的代码,在调用之后switch_to_32_pm,Qemu 开始发疯并不断清除屏幕并显示“从硬盘启动”。-curses(我必须补充一点,由于某种原因我无法运行( -curses: curses or iconv support is disabled)(我真的应该切换到 linux ......)。

这是相关代码:

引导程序

[org 0x7c00]
[bits 16]
    ; initialise stack
    mov bp, 0x9000
    mov sp, bp

    call switch_to_32_pm

    jmp $

%include "gdt.asm"
%include "switch_to_pm.asm"

[bits 32]
    BEGIN_PM:

        jmp $

; bootsector padding
times 510-($-$$) db 0
dw 0xaa55

gdt.asm

gdt_start:
    gdt_null: ; null descriptor
        dd 0x0
        dd 0x0

    gdt_code: ; code segment descriptor
        dw 0xffff ; limit (bits 0-15)
        dw 0x0 ; base (bits 0-15)
        db 0x0 ; base (bits 16 -23)
        db 10011010b ; 1st flags, type flags
        db 11001111b ; 2nd flags, Limit (bits 16-19)
        db 0x0 ; base (bits 24 - 31)

    gdt_data: ; data segment descriptor
        dw 0xffff ; limit (bits 0-15)
        dw 0x0 ; base (bits 0-15)
        db 0x0 ; base (bits 16 -23)
        db 10010010b ; 1st flags, type flags
        db 11001111b ; 2nd flags, Limit (bits 16-19)
        db 0x0 ; base (bits 24 - 31)

    gdt_end:
        gdt_descriptor:
            dw gdt_end - gdt_start - 1 ; size of the gdt
            dd gdt_start ; gdt start address

            ; some handy constants
            CODE_SEG equ gdt_code - gdt_start
            DATA_SEG equ gdt_data - gdt_start

switch_to_pm.asm

[bits 16]

; switch to 32bit protected mode
switch_to_32_pm:
    ; disable interrupts
    cli

    ; switch to 32bit protected mode
    lgdt [gdt_descriptor]

    mov eax, cr0 ; move cr0 to eax
    or eax, 0x1 ; set the first bit of eax
    mov cr0 , eax ; update cr0

    jmp CODE_SEG:init_32_pm ; make a far jump
                            ; this forces the cpu to flush it's cache
                            ; of pre fetched instructions

[bits 32]
; We're now in 32bit mode! 4gb hip hip hooray!
; init stack
init_32_pm:
    mov ax, DATA_SEG ; point all segment regs to our data sector in gdt 
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    mov ebp, 0x90000 ; set the stack at the top of free space
    mov esp, ebp

    call BEGIN_PM

标签: assemblyx86bootloaderosdevgdt

解决方案


推荐阅读