Skip to main content

Crate cargo_image_runner

Crate cargo_image_runner 

Source
Expand description

cargo-image-runner: A generic, highly customizable embedded/kernel development runner for Rust.

This library provides a flexible framework for building and running bootable images with support for multiple bootloaders (Limine, GRUB, none), image formats (ISO, FAT, directory), and boot types (BIOS, UEFI, hybrid).

§Quick Start

§Standalone Usage (no cargo_metadata or clap required)

use cargo_image_runner::{builder, Config};

let config = Config::from_toml_str(r#"
    [boot]
    type = "uefi"
    [bootloader]
    kind = "none"
    [image]
    format = "directory"
"#)?;

builder()
    .with_config(config)
    .workspace_root(".")
    .executable("target/x86_64-unknown-none/debug/my-kernel")
    .run()

§Using Cargo.toml Metadata (requires cargo-metadata feature)

use cargo_image_runner::builder;

// Load configuration from Cargo.toml and run
builder()
    .from_cargo_metadata()?
    .no_bootloader()
    .directory_output()
    .qemu()
    .run()

§Configuration in Cargo.toml

[package.metadata.image-runner.boot]
type = "uefi"

[package.metadata.image-runner.bootloader]
kind = "none"

[package.metadata.image-runner.image]
format = "directory"

§With Limine Bootloader

[package.metadata.image-runner.boot]
type = "hybrid"  # Supports both BIOS and UEFI

[package.metadata.image-runner.bootloader]
kind = "limine"
config-file = "limine.conf"

[package.metadata.image-runner.bootloader.limine]
version = "v8.4.0-binary"

[package.metadata.image-runner.variables]
TIMEOUT = "5"

Then create limine.conf:

timeout: {{TIMEOUT}}

/My Kernel
    protocol: limine
    kernel_path: boot():/boot/{{EXECUTABLE_NAME}}

§I/O Capture & Streaming

The IoHandler trait enables programmatic interaction with QEMU’s serial port:

use cargo_image_runner::{builder, Config, CaptureHandler};

let config = Config::from_toml_str(r#"
    [boot]
    type = "uefi"
    [bootloader]
    kind = "none"
    [image]
    format = "directory"
"#)?;

let result = builder()
    .with_config(config)
    .workspace_root(".")
    .executable("target/x86_64-unknown-none/debug/my-kernel")
    .io_handler(CaptureHandler::new())
    .run_with_result()?;

if let Some(output) = &result.captured_output {
    if let Some(serial) = &output.serial {
        println!("Serial output: {serial}");
    }
}

§Architecture

The library is built around three core traits:

  • Bootloader: Prepares bootloader files and configuration
  • ImageBuilder: Builds bootable images in various formats
  • Runner: Executes images (e.g., in QEMU)
  • IoHandler: Handles I/O from running instances

These traits allow easy extensibility for custom bootloaders, image formats, and runners.

§Custom Bootloader Example

use cargo_image_runner::bootloader::{Bootloader, BootloaderFiles, ConfigFile};
use cargo_image_runner::config::BootType;
use cargo_image_runner::core::{Context, Result};

struct MyBootloader;

impl Bootloader for MyBootloader {
    fn prepare(&self, ctx: &Context) -> Result<BootloaderFiles> {
        Ok(BootloaderFiles::new())
    }

    fn config_files(&self, ctx: &Context) -> Result<Vec<ConfigFile>> {
        Ok(Vec::new())
    }

    fn boot_type(&self) -> BootType {
        BootType::Uefi
    }

    fn name(&self) -> &str {
        "MyBootloader"
    }
}

§Features

  • default - Enables cli, cargo-metadata, uefi, bios, limine, iso, and qemu
  • cli - CLI binary and argument parsing (implies cargo-metadata)
  • cargo-metadata - Load config from Cargo.toml via cargo_metadata
  • uefi - UEFI boot support (includes OVMF firmware)
  • bios - BIOS boot support
  • limine - Limine bootloader (requires git)
  • grub - GRUB bootloader
  • iso - ISO image format
  • fat - FAT filesystem image format
  • qemu - QEMU runner
  • progress - Progress reporting (optional)

For standalone library use without clap or cargo_metadata:

[dependencies]
cargo-image-runner = { version = "0.5", default-features = false, features = ["uefi", "qemu"] }

Re-exports§

pub use crate::core::Error;
pub use crate::core::ImageRunner;
pub use crate::core::ImageRunnerBuilder;
pub use crate::core::Result;
pub use config::BootType;
pub use config::BootloaderKind;
pub use config::Config;
pub use config::ImageFormat;
pub use config::SerialConfig;
pub use config::SerialMode;
pub use runner::io::CaptureHandler;
pub use runner::io::CapturedIo;
pub use runner::io::IoAction;
pub use runner::io::IoHandler;
pub use runner::CapturedOutput;
pub use runner::RunResult;

Modules§

bootloader
Bootloader trait and built-in implementations (Limine, GRUB, none).
config
Configuration types and loading from [package.metadata.image-runner] in Cargo.toml.
core
Core types for the image runner pipeline: builder, context, and error handling.
firmware
Firmware management for UEFI boot (OVMF).
image
Image builder trait and built-in implementations (directory, ISO, FAT).
runner
Runner trait and QEMU implementation for executing bootable images.
util
Filesystem and hashing utility helpers.

Functions§

builder
Create a new image runner builder.