#os #pie #somehal

no-std pie-boot-if

Boot kernel code with mmu

10 releases (breaking)

Uses new Rust 2024

0.8.0 Sep 19, 2025
0.7.0 Aug 18, 2025
0.6.0 Jul 7, 2025
0.5.0 Jun 25, 2025
0.1.1 Jun 12, 2025

#2830 in Embedded development

Download history 206/week @ 2025-11-04 20/week @ 2025-11-11 40/week @ 2025-11-18 45/week @ 2025-11-25 29/week @ 2025-12-02 25/week @ 2025-12-09 32/week @ 2025-12-16 53/week @ 2025-12-23 37/week @ 2025-12-30 20/week @ 2026-01-06 35/week @ 2026-01-13 53/week @ 2026-01-20 105/week @ 2026-01-27 211/week @ 2026-02-03 340/week @ 2026-02-10 42/week @ 2026-02-17

708 downloads per month
Used in 29 crates (2 directly)

MIT license

6KB
109 lines

Somehal

为带有MMU功能的芯片设计的启动器,完成MMU初始化并将代码运行在指定地址。

动机

早期OS实现采用静态方式,用配置文件定义内核入口地址和加载地址,页表映射采用静态方式,将页表项定义在代码中,MMU初始化代码极简,只需要完成部分寄存器配置和设定页表地址,但不同硬件需要重新编译,人工设定加载地址。

为了实现动态加载,需要动态生成页表,需要引入一些复杂逻辑,如页表遍历、修改等,为方便调试又会引入串口驱动,设备树解析等,代码复杂度大大提升。而MMU启动前,加载地址与运行地址不一致,内核编译选项可能为no-pie,core和三方库代码无法管控,可能编译出地址相关的代码,执行到此处便会段错误(Linux 在此处只使用能生成位置无关的c代码,避免任何三方调用)。

设计思路

  1. 实现一个Bootloader,采用-C relocation-model=pic -Clink-args=-pie编译选项,编译成完全位置无关的程序,在其入口处,对rela.dyn段进行修复,将程序重定向到正确运行地址,保证MMU开启前程序正常运行。Bootloader负责配置页表,启动MMU并重定向到虚拟地址。

  2. 内核代码可采用-no-pie方式编译,在.boot_loader段存放Bootloader的bin程序,在入口处,通过汇编传递虚拟入口地址给Bootloader, 并跳转到Bootloader位置,Bootloader负责重定向到虚拟地址,跳转回虚拟入口。

  3. Build.rs中,通过bindeps-simple库,在build阶段,编译Bootloader,在代码中,通过include_bytes!嵌入到.boot_loader段。

    #[unsafe(link_section = ".boot_loader")]
    pub static LOADER_BIN: [u8; LOADER_BIN_LEN] = loader_bin();
    

Dependencies

~715KB
~14K SLoC