3.0.1 |
|
---|
#455 in 操作系统
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,您需要
- 截至2023.11.12的Rust nightly版本,您可以通过官方网站获取: https://www.rust-lang.net.cn/learn/get-started
- 使用Docker运行构建环境: https://www.docker.net.cn/get-started/
扩展
您最终将能够通过建议的扩展API开发自己的Trident 3扩展。
贡献
如果您想为此项目做出贡献,请 fork 它并提交带有您所需功能的pull请求。
- fork它。
- ????? (我忘了这里是什么)
- 提交带有您功能的pull请求。("【功能】描述您的功能")
- 赚钱?
有用的链接
要求
您需要一个带有 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
以下载core
和alloc
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::Command
在build.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 部分。
- BIOS 和 UEFI 二进制文件,其中包含实际的引导加载程序实现。
- 这些实现共享一个更高层次的 通用库。
- 两种实现都从 FAT 分区在运行时加载内核。此 FAT 分区是创建的
- 配置是从内核 ELF 文件的特殊部分读取的,该部分由
bootloader_api
库的entry_point
宏创建。
- 一个
springboard
库,用于创建运行给定内核的可引导磁盘镜像。此库是此项目的顶层 crate。- 该库在
build.rs
中构建 BIOS 和 UEFI 实现。 - 它提供了基于编译的 BIOS 和 UEFI 引导加载程序创建 FAT 格式可引导磁盘镜像的函数。
- 该库在
许可证
根据 Apache 许可证 2.0 版本授权 (LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)。
除非您明确表示,否则您提交给作品以包含在内的任何贡献,根据 Apache-2.0 许可证定义,应按上述方式授权,不附加任何额外条款或条件。
依赖项
~4–13MB
~182K SLoC