构建与运行
构建系统概述
Section titled “构建系统概述”OpenOS 使用两步构建过程:
- 编译内核 - 使用 Rust nightly 编译内核二进制
- 创建磁盘镜像 - 使用 bootloader 创建可引导的 BIOS 磁盘镜像
源代码 (Rust) → 内核二进制 → BIOS 磁盘镜像 → QEMU 运行详细构建流程
Section titled “详细构建流程”-
编译内核
Terminal window cargo build -p openos-kernel --target x86_64-unknown-none \-Zbuild-std=core,compiler_builtins,alloc \-Zbuild-std-features=compiler-builtins-mem这将生成内核二进制文件
target/x86_64-unknown-none/debug/openos-kernel -
创建用户态程序(可选)
Terminal window # 汇编用户态程序nasm -f elf64 user/hello.asm -o target/debug/hello.o# 链接ld -static -o target/debug/hello.elf target/debug/hello.o -
创建 initrd(可选)
Terminal window python3 tools/mkinitrd.py target/debug/initrd.img \hello.elf=target/debug/hello.elf -
创建磁盘镜像
Terminal window cargo run -p openos --target x86_64-unknown-linux-gnu -- \target/x86_64-unknown-none/debug/openos-kernel \target/debug/openos-bios.img \target/debug/initrd.img
QEMU 串口输出(推荐)
Section titled “QEMU 串口输出(推荐)”make run-serial优点:
- 输出到终端,便于调试
- 无头模式,适合服务器环境
- 可与 GDB 配合使用
QEMU 参数:
qemu-system-x86_64 \ -drive format=raw,file=target/debug/openos-bios.img \ -serial mon:stdio \ -display noneQEMU 图形显示
Section titled “QEMU 图形显示”make run优点:
- 可视化 VGA 输出
- 适合演示
QEMU 参数:
qemu-system-x86_64 \ -drive format=raw,file=target/debug/openos-bios.img \ -serial mon:stdioGDB 调试
Section titled “GDB 调试”make debug使用方法:
-
启动调试会话:
Terminal window make debug -
在另一个终端连接 GDB:
Terminal window gdb target/x86_64-unknown-none/debug/openos-kernel(gdb) target remote :1234(gdb) break kernel_main(gdb) continue -
常用 GDB 命令:
next/n- 单步执行step/s- 进入函数continue/c- 继续执行print/p- 打印变量backtrace/bt- 查看调用栈
Release 模式
Section titled “Release 模式”make release优化选项(在 Cargo.toml 中配置):
[profile.release]panic = "abort"opt-level = "s" # 优化大小lto = true # 链接时优化对于嵌入式环境,可以进一步优化:
# 使用 svelte 优化RUSTFLAGS="-C link-arg=-s" make release
# 使用 strip 去除符号strip target/x86_64-unknown-none/release/openos-kernel磁盘镜像格式
Section titled “磁盘镜像格式”OpenOS 使用 BIOS 引导的磁盘镜像:
偏移量 内容0x0000 引导扇区 (512 字节)0x0200 内核加载器0x1000 内核代码... 内核数据(initrd) 初始 ramdisk(如果存在)引导过程:
- BIOS 加载引导扇区到 0x7C00
- 引导加载器加载内核到 0x1000
- 引导加载器设置页表(高半内核映射)
- 跳转到内核入口点
修改内核入口
Section titled “修改内核入口”内核入口点在 kernel/src/main.rs 中定义:
#[no_mangle]pub extern "C" fn _start() -> ! { // 初始化代码 kernel_main(); loop { x86_64::instructions::hlt(); }}修改内存布局
Section titled “修改内存布局”内存布局在 kernel/src/arch/x86_64/linker.ld 中配置:
KERNEL_OFFSET = 0xFFFFFFFF80000000PHYSICAL_OFFSET = 0x100000
SECTIONS { . = KERNEL_OFFSET + PHYSICAL_OFFSET;
.text : AT(ADDR(.text) - KERNEL_OFFSET) { *(.text .text.*) }
.rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) { *(.rodata .rodata.*) }
.data : AT(ADDR(.data) - KERNEL_OFFSET) { *(.data .data.*) }
.bss : AT(ADDR(.bss) - KERNEL_OFFSET) { *(.bss .bss.*) }}QEMU 启动后立即退出
Section titled “QEMU 启动后立即退出”可能原因:
- 磁盘镜像损坏
- 内核 panic
解决方法:
- 检查 QEMU 输出的错误信息
- 使用
make debug启动调试 - 在内核入口点添加断点
可能原因:
- 串口驱动未初始化
- QEMU 参数错误
解决方法:
- 确保使用
make run-serial - 检查 QEMU 参数中是否有
-serial mon:stdio
优化方法:
- 使用增量编译:
cargo build(默认) - 使用并行编译:
cargo build -j$(nproc) - 使用
sccache缓存编译结果