# bootloader: a pure-Rust x86_64 bootloader for BIOS and UEFI

> bootloader is an experimental x86_64 boot chain written primarily in Rust, with separate BIOS and UEFI implementations. It suits Rust operating-system developers who need to package an ELF kernel into a bootable disk image, but its nightly toolchain and artifact-dependency requirements narrow the audience.

**rust-osdev/bootloader** — An experimental pure-Rust x86 bootloader

- Repository: https://github.com/rust-osdev/bootloader
- Stars: 1,702 · Forks: 241
- Language: Rust
- License: Apache-2.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/rust-osdev-bootloader

## What bootloader solves for x86_64 Rust kernels

bootloader addresses the gap between a compiled operating-system kernel and a disk image that BIOS or UEFI firmware can start. Its intended users are developers building x86_64 kernels in Rust, particularly kernels compiled as #![no_std] and #![no_main]. It does not provide a hosted userspace environment or a general-purpose boot utility. Its job is to package a kernel for the early boot path.

The project supports BIOS and UEFI and describes itself as experimental. The default `bootloader` package features enable both `bios` and `uefi`, with `mbrman` supporting BIOS disk structures and `gpt` supporting UEFI disk structures. The repository is not archived. The last push was on 2026-08-18, and recent releases include `v0.11.17` on 2026-07-27 and `v0.11.16` on 2026-07-18.

The kernel must cooperate with `bootloader_api`. A kernel defines `kernel_main`, registers it with `bootloader_api::entry_point!`, and receives a static mutable `BootInfo` value. The API documentation describes access to available memory, the framebuffer, and other boot information. A hosted executable or a kernel with a different startup convention is not the input described by this workflow.

## How the ELF metadata becomes a bootable disk image

The repository separates the system into three entities. The `bootloader_api` library defines the entry point, configuration types, and boot information used by the kernel. Its `entry_point` macro checks the kernel entry function signature, generates a `_start` symbol, and encodes configuration into a special ELF section. That section is the handoff between the compiled kernel and the image builder.

The `bios` and `uefi` directories contain the actual bootloader implementations. Both use a higher-level common library. At runtime, they load the kernel from a FAT partition. The top-level `bootloader` crate builds the BIOS and UEFI binaries and exposes image creation functions for them. Its dependencies include `fatfs`, `tempfile`, `serde_json`, `mbrman`, and `gpt`, which correspond to filesystem and disk-image work.

Configuration is read from the kernel ELF file rather than supplied only by the host application. The optional configuration argument can change settings such as the kernel stack size. This is useful for kernels with unusual early-boot requirements, but it makes the integration compile-time and artifact-oriented. The README does not document a command-line converter for arbitrary ELF files.

## Installing the toolchain and preparing a compatible kernel

The README requires a nightly Rust compiler and the `llvm-tools-preview` component:

```bash
rustup component add llvm-tools-preview
```

The kernel must depend on `bootloader_api`, use `#![no_std]` and `#![no_main]`, and expose an entry function with the documented signature:

```rust
fn kernel_main(boot_info: &'static mut bootloader_api::BootInfo) -> ! {
    // kernel startup
}
```

Register that function with the macro:

```rust
bootloader_api::entry_point!(kernel_main);
```

The macro generates `_start` and writes serialized configuration and metadata into the ELF file. If a linker script changes the entry symbol, the README says not to rename the generated entry point. A custom stack configuration can be supplied as follows:

```rust
const CONFIG: bootloader_api::BootloaderConfig = {
    let mut config = bootloader_api::BootloaderConfig::new_default();
    config.kernel_stack_size = 100 * 1024;
    config
};
bootloader_api::entry_point!(kernel_main, config = &CONFIG);
```

Build the kernel as an ELF executable for the bare-metal target:

```bash
cargo build --target x86_64-unknown-none
```

For firmware-specific support, the README names `x86_64-unknown-none` for BIOS and `x86_64-unknown-uefi` for UEFI. It also directs users to migration guides when moving from an older bootloader version.

## Creating BIOS or UEFI images in a Cargo workspace

The documented workflow uses a top-level `os` crate and a `kernel` subdirectory. Initialize the binary crate with:

```bash
cargo init --bin
```

Define the workspace in `Cargo.toml`:

```toml
[workspace]
resolver = "3"
members = []
```

Create the kernel package with:

```bash
cargo new kernel --bin
```

The workspace can use an artifact dependency to obtain the compiled kernel path during the build. Enable the unstable feature in `.cargo/config.toml`:

```toml
[unstable]
bindeps = true
```

Declare the kernel as a build dependency in `Cargo.toml`:

```toml
[build-dependencies]
kernel = { path = "kernel", artifact = "bin", target = "x86_64-unknown-none" }
```

The README requires nightly Rust for this integration and gives this toolchain configuration:

```toml
[toolchain]
channel = "nightly"
targets = ["x86_64-unknown-none", "x86_64-unknown-uefi"]
```

In `build.rs`, the host obtains the kernel executable path with `std::env::var_os("CARGO_BIN_FILE_MY_KERNEL_my-kernel")`, then uses `bootloader::UefiBoot` and `bootloader::BiosBoot` to create disk images. The repository points to `docs/create-disk-image.md` for the detailed template. The README says the resulting images can be handled in `main.rs`, for example with QEMU, but it does not provide a complete QEMU invocation in this section.

## Trade-offs, failure cases, and alternatives

The clearest limitation is experimental scope. The project targets x86_64 and supports two firmware paths, but the README does not provide production-readiness guarantees, recovery behavior, or a documented rollback procedure. It also does not document support for non-x86_64 architectures. A project with a mature boot chain, or one outside the Rust kernel ecosystem, may gain little from changing its boot architecture.

The integration is strict. The kernel must be `no_std`, must expose the expected entry function, and must contain the metadata section generated by `entry_point!`. Renaming `_start` in a linker script can break the documented handoff. A hosted Rust binary or an ELF executable without the expected metadata is the wrong input for this workflow.

A conventional alternative is a separate bootloader and image builder that starts an already-defined kernel through its own linker script, partition layout, and boot protocol. Bootloader takes a different approach: the Rust kernel ELF participates in the build, carries configuration in a generated section, and is placed into a FAT-based disk image. The choice is between an integrated Rust-specific boot chain and an externally managed boot process.

## Maintenance, licensing, and upgrade implications

The README states that the project is licensed under either Apache License, Version 2.0 or the MIT license, at the user's option. Contributions are described as dual licensed under those terms unless explicitly stated otherwise. This identifies the available license choices, but this article does not interpret their legal consequences.

The repository metadata identifies version `0.11.17`. The workspace dependencies for `bootloader_api` and the related common crates use the same version. The recent release history includes `v0.11.15` on 2026-02-01, followed by `v0.11.16` on 2026-07-18 and `v0.11.17` on 2026-07-27. The last push was on 2026-08-18. These records show recent activity, while the project itself remains explicitly experimental.

Upgrade cost comes from the nightly toolchain, artifact dependencies, possible API changes, and the need to follow `docs/migration` when moving from older releases. The README does not quantify migration effort or publish a complete compatibility matrix. A project should check the relevant migration guide and verify that its entry point and ELF metadata still match the selected release.

## Conclusion

Adopt bootloader when the operating system is an x86_64 Rust kernel that can use the entry_point macro, nightly artifact dependencies, and the documented FAT image format. Do not adopt it for a conventional hosted executable, a non-x86_64 target, or a production requirement that needs maturity claims the repository does not make. Before adoption, verify the kernel entry signature, ELF metadata section, firmware target, and image creation code in docs/create-disk-image.md.

## FAQ

### What does bootloader do for a Rust x86_64 kernel?

It creates BIOS and UEFI bootable disk images from a compiled kernel. The kernel uses `bootloader_api::entry_point!` so the ELF file contains the metadata and configuration needed by the bootloader.

### What are the requirements for using bootloader?

The README requires a nightly Rust compiler with `llvm-tools-preview`. The kernel must target x86_64, use `#![no_std]` and `#![no_main]`, and register an entry point with `bootloader_api::entry_point!`.

### Does bootloader support both BIOS and UEFI?

Yes. The default package features are `bios` and `uefi`, and the repository contains separate BIOS and UEFI implementations that share a common library and load the kernel from a FAT partition.

### Can bootloader create an image from any Rust executable?

The documented workflow is not a converter for arbitrary executables. The kernel must be built for the bare-metal x86_64 target and contain the entry-point metadata generated by `bootloader_api::entry_point!`.

## Sources

- [Issues](https://github.com/rust-osdev/bootloader/issues)
- [License: Apache-2.0](https://github.com/rust-osdev/bootloader/blob/main/LICENSE)
- [README](https://github.com/rust-osdev/bootloader/blob/main/README.md)
- [Releases](https://github.com/rust-osdev/bootloader/releases)
- [rust-osdev/bootloader on GitHub](https://github.com/rust-osdev/bootloader)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/rust-osdev-bootloader
