自制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
相关产品推荐
相关产品推荐

