Skip to main content

supermachine_kernel/
lib.rs

1//! Pre-built runtime assets for [supermachine], packaged as a Rust crate so
2//! embedders can `cargo add supermachine-kernel` instead of fetching binaries
3//! out of band — with **no network at build time** (the bytes are
4//! `include_bytes!`'d into the binary).
5//!
6//! ## A facade over per-arch sub-crates
7//!
8//! supermachine runs a **guest** Linux kernel matching the **host** arch (KVM
9//! on x86_64 runs an x86_64 guest; HVF on Apple Silicon runs an aarch64
10//! guest). Shipping every arch's kernel in one crate would bust the crates.io
11//! ~10 MiB cap and make every consumer download kernels they can't use.
12//!
13//! So this crate is a thin facade. The actual bytes live in per-arch
14//! sub-crates, declared as `[target.'cfg(target_arch = ...)']` dependencies:
15//!
16//! - [`supermachine-kernel-aarch64`] — aarch64 `Image` + init-oci + agent + smpark.ko
17//! - [`supermachine-kernel-x86-64`]  — x86_64 `bzImage` + busybox + agent
18//!
19//! Cargo only resolves/downloads the dependency whose `cfg(target_arch)`
20//! matches the **compilation target**, so building for x86_64 fetches *only*
21//! the x86 sub-crate, and aarch64 fetches *only* the arm one — never the
22//! other arch's multi-MiB kernel. This module re-exports the matching
23//! sub-crate's public API (`KERNEL_BYTES`, `extract_kernel_to`, …) so callers
24//! write arch-agnostic code:
25//!
26//! ```no_run
27//! // Same call on any host; you get that host's guest kernel.
28//! supermachine_kernel::extract_kernel_to(
29//!     std::path::Path::new("/tmp/supermachine/kernel"),
30//! ).unwrap();
31//! ```
32//!
33//! ## Arch-specific surface
34//!
35//! Most of the API is common to both sub-crates: `KERNEL_BYTES` / `KERNEL_LEN`,
36//! `SUPERMACHINE_AGENT_BYTES` / `_LEN`, and the `extract_kernel_to{,_with_parents}`
37//! / `extract_supermachine_agent_to{,_with_parents}` helpers.
38//!
39//! Some items exist only on one arch because the backends differ:
40//! - **aarch64 only:** `INIT_OCI_BYTES`, `SMPARK_KO_BYTES` (+ their `extract_*`
41//!   / `_LEN`). The HVF backend uses an `init-oci` PID-1 shim and an
42//!   `smpark.ko` module for multi-vCPU snapshot capture.
43//! - **x86_64 only:** `BUSYBOX_BYTES` (+ `extract_busybox_to*` / `BUSYBOX_LEN`).
44//!   The KVM backend builds the container rootfs (overlayfs + `switch_root`)
45//!   directly in the agent initramfs, using a bundled busybox.
46//!
47//! Code that needs an arch-specific item should gate it with
48//! `#[cfg(target_arch = "…")]` to stay portable.
49//!
50//! [supermachine]: https://crates.io/crates/supermachine
51//! [`supermachine-kernel-aarch64`]: https://crates.io/crates/supermachine-kernel-aarch64
52//! [`supermachine-kernel-x86-64`]: https://crates.io/crates/supermachine-kernel-x86-64
53
54#[cfg(target_arch = "aarch64")]
55pub use supermachine_kernel_aarch64::*;
56
57#[cfg(target_arch = "x86_64")]
58pub use supermachine_kernel_x86_64::*;
59
60// The facade only supports the arches supermachine itself runs on. Fail loudly
61// rather than silently exporting an empty API on an unsupported target.
62#[cfg(not(any(target_arch = "aarch64", target_arch = "x86_64")))]
63compile_error!(
64    "supermachine-kernel supports only aarch64 (HVF) and x86_64 (KVM) hosts; \
65     no guest kernel is bundled for this target_arch"
66);