#bootloader #operating-system #uefi #bios #kernel #disk-image #x86-64

springboard

同时适用于BIOS和UEFI系统的引导加载程序

3.0.1 2023年12月7日

#455 in 操作系统

Apache-2.0

56KB
1K SLoC

Springboard

版本:3.0.1/EARLY/UNRELEASED
许可: Apache-2.0
README: 你更愿意去哪里?
信息

上游引导加载程序和库源代码树可在此处找到。

一个实验性的x86_64引导加载程序,可在BIOS和UEFI系统上运行。使用Rust和部分内联汇编编写,可以在所有平台上构建,无需额外的构建时依赖项(只需一些 rustup 组件)。

Trident是一个操作系统,最初作为Medium和MBP2上的一系列文章的一部分开发,后来被纳入个人研究项目。

springboard 引导加载程序项目是 rust-osdev/bootloader 的分支,经过优化以满足Trident 3项目的需求。

截至2023.11,您需要

扩展

您最终将能够通过建议的扩展API开发自己的Trident 3扩展。

贡献

如果您想为此项目做出贡献,请 fork 它并提交带有您所需功能的pull请求。

  1. fork它。
  2. ????? (我忘了这里是什么)
  3. 提交带有您功能的pull请求。("【功能】描述您的功能")
  4. 赚钱?

要求

您需要一个带有 llvm-tools-preview 组件的nightly Rust编译器,该组件可以通过以下方式安装: rustup component add llvm-tools-preview

用法

要使用此crate,您首先需要调整内核以使其可引导。然后您可以从编译的内核创建可引导的磁盘映像。以下步骤将详细介绍。

如果您已经在使用较旧的 springboard crate 或 rust-osdev/bootloader crate,请按照我们的迁移指南操作。

内核

为了让您的内核与 springboard 兼容

  • 在内核的 Cargo.toml 中添加对 springboard_api crate 的依赖。
  • 您的内核二进制文件应该是 #![no_std]#![no_main]
  • 定义一个签名如下 fn kernel_main(boot_info: &'static mut springboard_api::BootInfo) -> ! 的入口点函数。函数名可以是任意的。
    • boot_info 参数提供了关于可用内存、帧缓冲区等信息。有关 springboard_api crate 的详细信息,请参阅API文档。
  • 使用 entry_point 宏注册入口点函数: springboard_api::entry_point!(kernel_main);
    • 该宏会检查您的入口点函数的签名,并为其生成一个 _start 入口点符号。(如果您使用链接脚本,请确保不要将入口点名称更改为其他名称。)
    • 要使用非标准配置,您可以将一个类型为 &'static springboard_api::BootloaderConfig 的第二个参数传递给 entry_point 宏。例如,您可以为您的内核要求特定的堆栈大小
      const CONFIG: springboard_api::BootloaderConfig = {
          let mut config = springboard_api::BootloaderConfig::new_default();
          config.kernel_stack_size = 100 * 1024; // 100 KiB
          config
      };
      springboard_api::entry_point!(kernel_main, config = &CONFIG);
      
  • 通过运行以下命令将内核编译为ELF可执行文件:cargo build --target x86_64-unknown-none。您可能需要在之前运行 rustup target add x86_64-unknown-none 以下载 corealloc crate 的预编译版本。
  • 感谢 entry_point 宏,编译后的可执行文件包含一个包含元数据和序列化配置的特殊部分,这将使 springboard crate 能够加载它。

引导

要将内核与引导程序结合并创建可引导磁盘镜像,请按照以下步骤操作

  • 将您的完整内核代码移动到 kernel 子目录中。
  • 在顶层创建一个定义工作区os crate。
  • 添加对 bootloader crate 的 build-dependencies
  • 创建一个build.rs 编译脚本。
  • 设置工件依赖项 以将您的 kernel crate 添加为 build-dependency
    # in Cargo.toml
    [build-dependencies]
    kernel = { path = "kernel", artifact = "bin", target = "x86_64-unknown-none" }
    
    # .cargo/config.toml
    
    [unstable]
    # enable the unstable artifact-dependencies feature, see
    # https://doc.rust-lang.net.cn/nightly/cargo/reference/unstable.html#artifact-dependencies
    bindeps = true
    
    或者,您可以使用 std::process::Commandbuild.rs 脚本中调用您内核的构建命令。
  • 获取内核可执行文件的路径。当使用工件依赖项时,您可以使用 std::env::var_os("CARGO_BIN_FILE_MY_KERNEL_my-kernel") 获取此路径。
  • 使用 springboard::UefiBoot 和/或 springboard::BiosBoot 创建包含您的内核的可引导磁盘镜像。
  • 在您的 main.rs 函数中处理可引导磁盘镜像。例如,使用 QEMU 运行它们。

请参阅我们的 磁盘镜像创建模板 以获取更详细的示例。

架构

此项目分为三个独立实体

  • 一个包含入口点、配置和引导信息定义的 springboard_api 库。
    • 内核应将该库作为正常的 cargo 依赖项包含。
    • 提供的 entry_point 宏将配置设置编码到编译的内核可执行文件的单独 ELF 部分。
  • BIOSUEFI 二进制文件,其中包含实际的引导加载程序实现。
    • 这些实现共享一个更高层次的 通用库
    • 两种实现都从 FAT 分区在运行时加载内核。此 FAT 分区是创建的
    • 配置是从内核 ELF 文件的特殊部分读取的,该部分由 bootloader_api 库的 entry_point 宏创建。
  • 一个 springboard 库,用于创建运行给定内核的可引导磁盘镜像。此库是此项目的顶层 crate。
    • 该库在 build.rs 中构建 BIOS 和 UEFI 实现。
    • 它提供了基于编译的 BIOS 和 UEFI 引导加载程序创建 FAT 格式可引导磁盘镜像的函数。

许可证

根据 Apache 许可证 2.0 版本授权 (LICENSE-APACHEhttp://www.apache.org/licenses/LICENSE-2.0)。

除非您明确表示,否则您提交给作品以包含在内的任何贡献,根据 Apache-2.0 许可证定义,应按上述方式授权,不附加任何额外条款或条件。

依赖项

~4–13MB
~182K SLoC