- Notifications
You must be signed in to change notification settings - Fork215
An experimental pure-Rust x86 bootloader
License
Apache-2.0, MIT licenses found
Licenses found
rust-osdev/bootloader
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
An experimental x86_64 bootloader that works on both BIOS and UEFI systems. Written in Rust and some inline assembly, buildable on all platforms without additional build-time dependencies (just somerustup
components).
You need a nightlyRust compiler with thellvm-tools-preview
component, which can be installed throughrustup component add llvm-tools-preview
.
To use this crate, you need to adjust your kernel to be bootable first. Then you can create a bootable disk image from your compiled kernel. These steps are explained in detail below.
If you're already using an older version of thebootloader
crate, follow ourmigration guides.
To make your kernel compatible withbootloader
:
- Add a dependency on the
bootloader_api
crate in your kernel'sCargo.toml
. - Your kernel binary should be
#![no_std]
and#![no_main]
. - Define an entry point function with the signature
fn kernel_main(boot_info: &'static mut bootloader_api::BootInfo) -> !
. The function name can be arbitrary.- The
boot_info
argument provides information about available memory, the framebuffer, and more. See the API docs forbootloader_api
crate for details.
- The
- Use the
entry_point
macro to register the entry point function:bootloader_api::entry_point!(kernel_main);
- The macro checks the signature of your entry point function and generates a
_start
entry point symbol for it. (If you use a linker script, make sure that you don't change the entry point name to something else.) - To use non-standard configuration, you can pass a second argument of type
&'static bootloader_api::BootloaderConfig
to theentry_point
macro. For example, you can require a specific stack size for your kernel:constCONFIG: bootloader_api::BootloaderConfig ={letmut config = bootloader_api::BootloaderConfig::new_default(); config.kernel_stack_size =100*1024;// 100 KiB config};bootloader_api::entry_point!(kernel_main, config =&CONFIG);
- The macro checks the signature of your entry point function and generates a
- Compile your kernel to an ELF executable by running
cargo build --target x86_64-unknown-none
. You might need to runrustup target add x86_64-unknown-none
before to download precompiled versions of thecore
andalloc
crates. - Thanks to the
entry_point
macro, the compiled executable contains a special section with metadata and the serialized config, which will enable thebootloader
crate to load it.
To combine your kernel with a bootloader and create a bootable disk image, follow these steps:
- Move your full kernel code into a
kernel
subdirectory. - Create a new
os
crate at the top level that defines aworkspace. - Add a
build-dependencies
on thebootloader
crate. - Create a
build.rs
build script. - Set up anartifact dependency to add your
kernel
crate as abuild-dependency
:# in Cargo.toml[build-dependencies]kernel = {path ="kernel",artifact ="bin",target ="x86_64-unknown-none" }
Alternatively, you can use# .cargo/config.toml[unstable]# enable the unstable artifact-dependencies feature, see# https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#artifact-dependenciesbindeps =true
std::process::Command
to invoke the build command of your kernel in thebuild.rs
script. - Obtain the path to the kernel executable. When using an artifact dependency, you can retrieve this path using
std::env::var_os("CARGO_BIN_FILE_MY_KERNEL_my-kernel")
- Use
bootloader::UefiBoot
and/orbootloader::BiosBoot
to create a bootable disk image with your kernel. - Do something with the bootable disk images in your
main.rs
function. For example, run them with QEMU.
See ourdisk image creation template for a more detailed example.
This project is split into three separate entities:
- A
bootloader_api
library with the entry point, configuration, and boot info definitions.- Kernels should include this library as a normal cargo dependency.
- The provided
entry_point
macro will encode the configuration settings into a separate ELF section of the compiled kernel executable.
- BIOS andUEFI binaries that contain the actual bootloader implementation.
- The implementations share a higher-levelcommon library.
- Both implementations load the kernel at runtime from a FAT partition. This FAT partition is created
- The configuration is read from a special section of the kernel's ELF file, which is created by the
entry_point
macro of thebootloader_api
library.
- A
bootloader
library to create bootable disk images that run a given kernel. This library is the top-level crate in this project.- The library builds the BIOS and UEFI implementations in the
build.rs
. - It provides functions to create FAT-formatted bootable disk images, based on the compiled BIOS and UEFI bootloaders.
- The library builds the BIOS and UEFI implementations in the
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE orhttp://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT orhttp://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
About
An experimental pure-Rust x86 bootloader
Resources
License
Apache-2.0, MIT licenses found
Licenses found
Uh oh!
There was an error while loading.Please reload this page.