用Bochs 2.6.9和GeekOS 0.3.0搭建你的第一个‘玩具’操作系统:Project0实战记录

发布时间:2026/5/30 9:10:23

用Bochs 2.6.9和GeekOS 0.3.0搭建你的第一个‘玩具’操作系统:Project0实战记录 从零构建GeekOS玩具操作系统Bochs调试与内核修改实战指南当屏幕上首次闪现Welcome to GeekOS时那种亲手启动一个操作系统的成就感是任何理论课程都无法替代的。本文将带你深入GeekOS 0.3.0的Project0实现细节不仅教你搭建环境更会解密这个微型操作系统从启动到显示欢迎信息的完整流程。不同于普通安装教程我们将聚焦三个核心维度Bochs调试器逆向分析启动过程、GeekOS内核代码修改实践以及软盘映像的二进制级操作适合已经掌握基础Linux命令和C语言的开发者深入操作系统原理。1. 开发环境精准配置1.1 构建Bochs 2.6.9调试环境在Ubuntu 20.04 LTS上配置支持调试的Bochs需要特别注意依赖项的完整性。以下是经过验证的依赖安装方案# 基础编译工具链 sudo apt-get install build-essential gcc-multilib # X11和GUI支持 sudo apt-get install xorg-dev libgtk2.0-dev # 其他必要组件 sudo apt-get install bison libreadline-dev编译Bochs时关键在configure阶段启用调试器和反汇编功能./configure --enable-debugger --enable-disasm \ --with-x11 --with-term \ --enable-all-optimizations make -j$(nproc) sudo make install常见陷阱如果遇到undefined reference to clock_gettime错误需要额外链接-lrt库export LDFLAGS-lrt ./configure [...原有参数...]1.2 GeekOS 0.3.0的特殊编译处理GeekOS的Makefile需要针对现代GCC进行适配修改。主要调整点集中在geekos-0.3.0/src/project0/build/Makefile# 修改前 CC_GENERAL_OPTS : $(GENERAL_OPTS) -Werror # 修改后移除-Werror并添加安全选项 CC_GENERAL_OPTS : $(GENERAL_OPTS) -fno-stack-protector -O0关键参数说明-fno-stack-protector禁用栈保护避免内核代码触发安全检查-O0关闭优化确保调试信息准确对应源代码-m32强制生成32位代码需安装gcc-multilib2. Bochs调试器深度探索2.1 启动流程逆向分析配置.bochsrc时以下调试相关参数必不可少# 启用Magic Break支持在代码中插入0x1B0实现断点 magic_break: enabled1 # 禁用CPU优化确保单步调试准确 cpu: count1, ips1000000, modelcorei7_haswell_4770, reset_on_triple_fault1启动Bochs调试模式bochs -q -f .bochsrc在调试器界面中这些命令至关重要命令功能描述示例使用场景s单步执行跟踪BIOS初始化过程c继续运行跳过已知正常代码段x /16i反汇编16条指令分析无符号代码区域info eflags查看CPU标志寄存器检查中断是否启用dump_cpu显示所有寄存器状态上下文切换时状态验证2.2 关键断点设置技巧在GeekOS启动过程中这些地址值得关注# 主引导记录(MBR)加载点 vb 0x7C00 # 内核入口点通常在链接脚本中定义 lb _start # 屏幕输出函数追踪Welcome消息来源 lb Print_String当执行到断点时使用print-stack命令查看调用栈0x00007c00 in ?? () Next at t0 (0) [0x00007c00] 0000:7c00 (unk. ctxt): cli ; fa bochs:1 print-stack Stack address size 4 | STACK 0x00006f00 [0x0006f000] (*) | STACK 0x00006f04 [0x0006f004] (*)3. GeekOS内核修改实战3.1 定制欢迎消息修改src/project0/geekos/main.c中的启动代码// 原始版本 Print(Welcome to GeekOS!\n); // 修改版本 - 添加启动时间和版本信息 Print(GeekOS 0.3.0 - Project0\n); Print(Boot Time: ); Print_Time(); Print(\nSystem Initializing...\n);需要实现Print_Time()函数读取CMOS时钟static void Print_Time() { unsigned char hour inb(0x70); unsigned char minute inb(0x72); Print_Byte(hour); Print(:); Print_Byte(minute); }3.2 软盘映像结构解析GeekOS生成的fd.img包含三个关键部分引导扇区512字节位于映像开头包含MBR和分区表由fd_boot.bin生成设置代码通常位于第二个扇区负责切换到保护模式来自setup.bin内核镜像包含编译后的C代码由kernel.bin提供使用dd命令验证各组件# 提取引导扇区 dd iffd.img ofboot.bin bs512 count1 # 反汇编验证 ndisasm -b 16 boot.bin4. 高级调试技巧4.1 内存断点监控当需要监控特定内存区域时Bochs提供强大的内存断点功能# 设置写入断点监控0x000B8000显存区域 watch write phys 0x000B8000 # 设置执行断点捕获未知代码执行 watch exec linear 0x001000004.2 自动化调试脚本创建debug.bochs脚本自动化常见调试任务# 启动时自动执行的调试命令 display registers break 0x7C00 continue when 0x7C00 { print-stack disassemble 0x7C00 0x7C20 }使用脚本启动bochs -q -f .bochsrc -rc debug.bochs4.3 修改代码后的快速测试流程修改内核代码后重新编译make clean make验证新生成的fd.imgfile fd.img # 应显示DOS floppy启动Bochs并附加调试器bochs -q -f .bochsrc -rc debug.bochs若出现异常使用show faults命令查看CPU异常信息当你在调试器中看到自己修改的启动消息可以尝试更深入的内核修改比如添加简单的系统调用或修改任务调度算法。每次修改后记得使用dd命令确保更改正确写入软盘映像dd ifkernel.bin offd.img bs512 seek1 convnotrunc

相关新闻