编写简易OS时Qemu屏幕无内核输出的问题排查与解决
问题诊断与修复方案
核心问题1:内核加载地址与链接地址不匹配
你的引导加载器把内核加载到物理地址0x10000(es=0x1000 + bx=0x0000 → 0x1000<<4 + 0x0000 = 0x10000),但链接脚本指定内核运行地址是0x100000,这会导致call kernel_main跳转到错误内存位置,内核代码根本没执行。
修复步骤:
修改linker.ld,把内核起始地址改为0x10000:
ENTRY(kernel_main) SECTIONS { . = 0x00010000; // 和加载地址保持一致 .text : { *(.text) } .rodata : { *(.rodata) } .data : { *(.data) } .bss : { *(.bss) } }
同步修改bootloader.asm里的kernel_main定义:
kernel_main equ 0x00010000 // 和链接地址匹配
核心问题2:VGA文本模式缺少属性字节
VGA文本模式每个字符占2字节:第1字节是ASCII码,第2字节是显示属性(前景/背景色等)。你只写入了'A',属性字节默认是0(黑底黑字),导致字符完全看不见。
修复步骤:
修改kernel.c,添加可见的属性字节(比如0x0F表示黑底白字):
void kernel_main() { char* video_memory = (char*)0xB8000; video_memory[0] = 'A'; video_memory[1] = 0x0F; // 黑底白字,确保能看见 }
辅助优化:添加磁盘加载错误检查
int 0x13磁盘读调用后没有检查是否成功,如果加载失败会直接进入保护模式,后续操作全无效。可以加个简单的错误提示:
int 0x13 jc disk_error // CF标志位被置位说明读盘失败 ; ... 原有代码 ... disk_error: mov ah, 0x0E mov al, 'E' int 0x10 // 实模式下输出'E'提示错误 jmp hang
验证修复
执行make clean && make重新编译,然后用QEMU启动:qemu-system-i386 os-image.bin,此时屏幕左上角应该能看到清晰的白色'A'。
内容的提问来源于stack exchange,提问作者Hui Xiao
相关产品推荐
相关产品推荐

