bootswain is a Rust workspace for repeatable host-side board flashing,
firmware inspection, serial probing, and validation workflows around U-Boot.
The current focus is ROCKPro64 firmware work, with Raspberry Pi 3 B+ boot
partition tooling also present as release-candidate support.
The project is intentionally evidence-gated: release-candidate artifacts are
easy to build and inspect, but stable support claims require real validation
data under validation/<board>/stable/.
- Inspect raw and zstd-compressed image artifacts.
- Flash SD or removable block devices with dry-run and verification modes.
- Run reproducible ROCKPro64 USB and serial validation flows.
- Package ROCKPro64 RK3399 U-Boot, TF-A, SPI installer, and shared-storage images with Nix.
- Package a Raspberry Pi 3 B+ FAT boot partition image with Raspberry Pi firmware, DTB, and U-Boot.
- Expose NixOS modules for board boot-file installation and bootable profiles.
ROCKPro64 is the primary target. The SPI installer target is flashable as a release candidate; shared-storage image flashing remains gated unless the operator explicitly allows non-flashable artifacts for lab work.
Raspberry Pi 3 B+ support currently produces a release-candidate boot partition
image. It does not claim stable support until validation evidence is imported
under validation/raspberrypi3bplus/stable/.
Enter the development shell:
nix developBuild and test the workspace:
cargo build --workspace
cargo test --workspaceRun the flake checks:
nix flake checkList Nix-built flash targets:
nix run .#flash -- --list-targetsDry-run a ROCKPro64 SPI installer flash:
nix run .#flash -- \
--target rockpro64-spi-installer \
--device /dev/sdX \
--dry-runDry-run a Raspberry Pi 3 B+ boot partition flash:
nix run .#flash -- \
--target raspberrypi3bplus-boot-partition \
--device /dev/sdX \
--dry-runInspect an image:
bootswain image inspect --image /path/to/spi.installer.imgInspect an image with JSON output:
bootswain image inspect \
--image /path/to/spi.installer.img \
--jsonFlash an SD card after reviewing the dry-run output:
bootswain flash sd \
--image /path/to/spi.installer.img \
--device /dev/sdX \
--verifyRun one ROCKPro64 USB probe trial:
bootswain probe rockpro64-usb \
--image /path/to/spi.installer.img \
--port /dev/ttyUSB0 \
--out ./probe-outputRun the generic ARM64 QEMU smoke validator:
bootswain validate qemu-arm64 \
--plan validation/qemu-arm64/boot-smoke.json \
--u-boot /path/to/u-boot.bin \
--qemu qemu-system-aarch64 \
--out ./qemu-outputCommon outputs include:
.#bootswain/.#default: the CLI package..#flash: a wrapper app for built release-candidate flash targets..#rockpro64-release-bundle: ROCKPro64 release-candidate bundle..#rockpro64-release-bundle-experimental: ROCKPro64 experimental bundle..#raspberrypi3bplus-release-bundle: Raspberry Pi 3 B+ release-candidate bundle.nixosModules.rockpro64andnixosModules.rockpro64Bootable.nixosModules.raspberryPi3BPlusandnixosModules.raspberryPi3BPlusBootable.
Downstream flakes can import a bootable profile and layer their own filesystems, users, services, and deployment policy on top:
{
inputs.bootswain.url = "git+https://github.com/caniko/bootswain.git";
outputs = {
nixpkgs,
bootswain,
...
}: {
nixosConfigurations.rockpro64 = nixpkgs.lib.nixosSystem {
system = "aarch64-linux";
modules = [
bootswain.nixosModules.rockpro64Bootable
./configuration.nix
];
};
nixosConfigurations.rpi3bplus = nixpkgs.lib.nixosSystem {
system = "aarch64-linux";
modules = [
bootswain.nixosModules.raspberryPi3BPlusBootable
./configuration.nix
];
};
};
}Stable promotion is blocked until the relevant board directory contains real lab evidence, including the validation run, serial logs, artifact manifest, and exact image checksums.
For ROCKPro64, stable promotion requires:
validation/rockpro64/stable/validation-run.json- serial logs for every claimed scenario
- a successful build of
.#rockpro64-stable-release-bundle
For Raspberry Pi 3 B+, stable promotion requires equivalent evidence under:
validation/raspberrypi3bplus/stable/
The repository uses Nix for repeatable tooling and generated GitHub Actions CI for
testing. The generated CI workflows run package tests and clippy through
nix develop, and run nix flake check.
Useful local commands:
nix develop
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- --deny warnings
cargo test --workspace
nix flake check --no-buildDocumentation lives in docs/ and can be served with:
cd docs
mdbook serveThe website lives in website/ and can be served with:
cd website
zola serve