You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自制Bootloader异常求助:切换保护模式后黑屏问题

自制简单Bootloader遇到保护模式切换问题

我之前跟着教程写过一个Bootloader,但太复杂根本看不懂。现在想靠自己的知识和搜索工具做个简单的,目标是初始化功能后把控制权交给内核。

我需要操作视频缓冲区,所以一开始就激活了视频模式,但被告知转交内核前必须切换到保护模式,这里出问题了——我不清楚具体步骤。为了调试,我加了两个画点的标签,但有时只显示一个点,现在直接黑屏了。

软盘已经成功加载,用QEMU测试,但没法配合GDB调试。


Bootloader代码

[bits 16]
[org 0x7c00]

start:
    cli

    ; Initialize stack
    mov ax, 0x8000
    mov ss, ax
    xor sp, sp

    ; Initialize data segments
    xor ax, ax
    mov ds, ax
    mov es, ax

    ; Switch to Video Mode
    mov ax, 0x0013
    int 0x10   

    call debug 

    
    lgdt [gdtr]
    
    jmp 0x08:skip 

[bits 32]
skip:

    mov eax, cr0
    or al, 1
    mov cr0, eax    

    mov ax, 0x10 
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax 
    jmp 0x08:0x1000 

debug:
    mov ax, 0xA000
    mov es, ax
    mov di, 320*100 + 100
    mov al, 0x0F
    stosb

debug2:
    mov ax, 0xA000
    mov es, ax
    mov di, 320*100 + 300
    mov al, 0x0F
    stosb


section .gdtr
gdtr:
    dw 0x17FF
gdt:
    dd 0x00000000, 0x00000000
    dd 0x00FFFFFF, 0x00CF9A00

; Boot signature
times 422-($-$$) db 0
dw 0xAA55

注:如果填充到510字节,生成的二进制文件大小约550字节左右。


内核相关文件

linker.ld

ENTRY(kernel_main)
SECTIONS {
    . = 0x1000;

    .text : {
        *(.text)
    }
    .data : {
        *(.data)
    }
    .bss : {
        *(.bss)
    }
}

entry.asm

section .text
global _start
extern kernel_main

_start:
    ; Initialize stack
    mov esp, mainFnStack + 4096 ; Point to the top of the stack space

    ; Draw dot for debugging
    mov ax, 0xA000
    mov es, ax
    mov di, 320*100 + 200
    mov al, 0x0F
    stosb

    ; Call main kernel function
    call kernel_main

    ; Infinite loop to halt execution
    jmp $

section .bss
mainFnStack resb 4096  ; Allocate 4096 bytes for the stack

Makefile文件

Bootloader的Makefile

ASMC = nasm
FLAGS = -f bin -O3
SRC = boot.asm
DEST = ../../bin/boot.bin

all: $(DEST)

$(DEST): $(SRC)
    $(ASMC) $(FLAGS) $< -o $@

clean:
    rm -f $(DEST)

内核的Makefile

CC = gcc
LD = ld
ASMC = nasm
CFLAGS = -ffreestanding -c
ASMFLAGS = -f elf64
LDFLAGS = -o ../../bin/kernel.bin -T linker.ld
SRC_C = $(wildcard *.c */*.c)
SRC_ASM = $(wildcard *.asm */*.asm)
OBJ_C = $(patsubst %.c, obj/%.o, $(SRC_C))
OBJ_ASM = $(patsubst %.asm, obj/%.o, $(SRC_ASM))

all: ../../bin/kernel.bin

../../bin/kernel.bin: $(OBJ_C) $(OBJ_ASM)
    $(LD) $(LDFLAGS) $(OBJ_ASM) $(OBJ_C)

obj/%.o: %.c
    @mkdir -p $(@D)
    $(CC) $(CFLAGS) $< -o $@

obj/%.o: %.asm
    @mkdir -p $(@D)
    $(ASMC) $(ASMFLAGS) $< -o $@

clean:
    rm -rf obj ../../bin/kernel.bin

项目根目录的Makefile

all:
    $(MAKE) -C src/kernel
    $(MAKE) -C src/bootloader
    dd if=/dev/zero of=bin/floppy.img bs=1k count=1440 
    dd if=bin/boot.bin of=bin/floppy.img conv=notrunc seek=0
    dd if=bin/kernel.bin of=bin/floppy.img bs=512 seek=1 conv=notrunc



clean:
    $(MAKE) -C src/kernel clean
    $(MAKE) -C src/bootloader clean
    rm -f bin/floppy.img

内容的提问来源于stack exchange,提问作者Fabboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:05:38