Install bootimage
masterInstall the bootimage cargo subcommand using cargo to enable building bootable disk images from Rust OS kernels.
> cargo install bootimagerepository·master·Indexed 21 days ago
https://github.com/rust-osdev/bootimageA cargo subcommand and library (version 0.10.4) used to create bootable disk images from Rust-based operating system kernels. It automates the process of building a kernel and combining it with a bootloader, providing a CLI for image creation and a runner for executing kernels in QEMU. The tool requires the bootloader crate as a dependency and utilizes llvm-objcopy for binary conversion.
Install the bootimage cargo subcommand using cargo to enable building bootable disk images from Rust OS kernels.
> cargo install bootimageYou can automate running your kernel in QEMU by setting bootimage runner as a custom runner in your .cargo/config file.
Once configured, you can run your kernel using cargo xrun (or your preferred cargo runner command), passing QEMU arguments after a -- separator.
# .cargo/config
[target.'cfg(target_os = "none")']
runner = "bootimage runner"cargo xrun --target your_custom_target.json [other_args] -- [qemu args]To use bootimage, you must add the bootloader crate as a dependency in your Cargo.toml.
Version Requirements:
bootimage 0.7.0 and later: Use bootloader version 0.5.1 or higher.bootimage 0.6.6 and earlier: Use earlier bootloader versions.If you use a custom bootloader name, you can use Cargo's dependency renaming functionality.
# in your Cargo.toml
[dependencies]
bootloader = "0.9.8"You can automate the process of building and running your kernel by setting bootimage runner as the target runner in your .cargo/config file. This is typically done for bare-metal targets (e.g., target_os = "none"). When configured this way, running cargo test or cargo run will automatically invoke the bootimage runner to create a disk image and launch it in QEMU.
[target.'cfg(target_os = "none")']
runner = "bootimage runner"Build your kernel project and create a bootable disk image using the cargo bootimage command. This command invokes cargo build (forwarding all passed options) and then builds the specified bootloader together with your kernel.
cargo bootimage --target your_custom_target.json [other_args]bootimage crate supports running unit and integration tests for your kernel. To use this, you must implement the custom_tests_framework feature of Rust in your kernel project.The behavior of the bootimage runner subcommand can be customized by adding a [package.metadata.bootimage] table to your Cargo.toml. This allows you to define which emulator to use, pass specific arguments to the runner, and configure how test executables are handled (success codes and timeouts).
[package.metadata.bootimage]
# The command invoked with the created bootimage (the "{}" will be replaced with the path to the bootable disk image)
run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"]
# Additional arguments passed to the run command for non-test executables
run-args = []
# Additional arguments passed to the run command for test executables
test-args = []
# An exit code that should be considered as success for test executables
test-success-exit-code = {integer}
# The timeout for running a test (in seconds)
test-timeout = 300You can customize the behavior of cargo bootimage by adding a [package.metadata.bootimage] table to your Cargo.toml file.
Currently, you can specify the cargo subcommand used to build the kernel using the build-command key. For example, if you are using cargo-xbuild instead of standard cargo, you should set this to ["xbuild"].
[package.metadata.bootimage]
# The cargo subcommand that will be used for building the kernel.
# For building using the `cargo-xbuild` crate, set this to `xbuild`.
build-command = ["build"]You can customize the behavior of bootimage by adding a [package.metadata.bootimage] table to your Cargo.toml. This allows you to define the build command, the runner command (e.g., QEMU), and specific arguments for running or testing executables.
[package.metadata.bootimage]
# The cargo subcommand that will be used for building the kernel.
# For building using the `cargo-xbuild` crate, set this to `xbuild`.
build-command = ["build"]
# The command invoked with the created bootimage (the "{}" will be replaced
# with the path to the bootable disk image)
# Applies to `bootimage run` and `bootimage runner`
run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"]
# Additional arguments passed to the run command for non-test executables
# Applies to `bootimage run` and `bootimage runner`
run-args = []
# Additional arguments passed to the run command for test executables
# Applies to `bootimage runner`
test-args = []
# An exit code that should be considered as success for test executables
# test-success-exit-code = {integer}
# The timeout for running a test through `bootimage test` or `bootimage runner` (in seconds)
test-timeout = 300
# Whether the `-no-reboot` flag should be passed to test executables
test-no-reboot = trueThe cargo-bootimage tool is designed to be invoked as a Cargo subcommand. You should run it using the following command structure:
cargo bootimage
Note that the tool expects to be called via Cargo; direct execution of the cargo-bootimage binary without the bootimage subcommand argument will result in an error.
cargo bootimageThe Builder struct is the primary entry point for programmatically building a kernel and combining it with a bootloader to create a bootable disk image.
Workflow:
Builder using Builder::new(). It will attempt to find your Cargo.toml via the CARGO_MANIFEST_DIR environment variable or by searching the filesystem.build_kernel() to execute the cargo build command for your kernel. This returns a list of paths to the resulting executable binaries.create_bootimage() to build the bootloader and combine it with your kernel binary into a final disk image at the specified output path.use bootimage::builder::Builder;
use bootimage::config::Config;
use std::path::PathBuf;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. Initialize the builder
let mut builder = Builder::new(Some(PathBuf::from("./Cargo.toml")))?;
// 2. Define configuration (Config is provided by the crate)
let config = Config::default();
let args = vec!["build".to_string()];
// 3. Build the kernel
let kernel_bins = builder.build_kernel(&args, &config, false)?;
let kernel_bin = &kernel_bins[0];
// 4. Create the bootable disk image
builder.create_bootimage(
builder.manifest_path(), // kernel manifest path
kernel_bin, // path to built kernel binary
&PathBuf::from("bootable.bin"), // output path
false // quiet mode
)?;
Ok(())
}The bootimage builder expects specific metadata in the bootloader crate's Cargo.toml to correctly identify the target and build configuration. If you are using a custom bootloader or a specific version of the official bootloader crate, ensure the following keys are present in the [package.metadata] section:
bootloader.target: A string specifying the target JSON file or path used for building the bootloader.bootloader.build-std: (Optional) A string specifying the component to be passed to -Zbuild-std= (e.g., core,alloc).Note: If you are using the official bootloader crate, you must use at least version 0.5.1 to support this metadata format.