9.6 KiB
Boot images and stage0
Development reference and historical context. For current operating instructions, use the user manual. Acceptance applies only to the source and artifacts identified in each record.
Documentation index · First build · Implementation status
FDS keeps the machine's boot files on internal NVMe and its operating system on a
removable SYSTEM cartridge. The Pi firmware loads the kernel and a small initial
filesystem. Its Rust fds-stage0 program finds the partition named FDS_SYSTEM,
mounts it read-only, and hands control to native s6. Device names such as sda
are never used as cartridge identities.
The software boot path has passed on an ARM virtual machine using the actual
FDS Pi kernel. That does not verify Pi firmware, NVMe, RP1, display output, USB
power or physical boot speed. Those checks are deferred until the machine is
assembled. M5 now provides an ordinary-user FDS> console with a temporary home
and measured boot events. Password login remains locked; this is an intentional
local single-user session. The M2 test VM separately offers a temporary root
development shell. See native init and performance reports.
Build on the workstation
Use the Arch host setup first. In addition to its original tools,
install host lz4, zstd, util-linux, e2fsprogs and libarchive if missing.
They supply initramfs compression, independent GPT inspection and the initial
VM's filesystem/archive tools; these are build/test dependencies.
Python 3.14+ reads zstd-compressed XBPS archives. Filesystem builders are obtained
as verified Void packages in .host/image-tools, separate from the build container.
From the repository root, run sequentially:
make bootstrap
make rootfs PROFILE=cli
make initramfs
make system-card PROFILE=cli
make boot-volume
make rootfs-test
make init-test
make boot-test
The rootfs build includes the FDS CLI, base Dasung daemon, native s6 database, and
the kernel's matching modules. Its first kernel cross-build is substantial;
progress is recorded in out/logs/xbps-fds-kernel.log. make kernel also builds
that kernel independently. Later calls reuse its package only when recorded
source inputs and every exported payload hash still match. To force a kernel
rebuild, run ./tools/build-kernel --rebuild. This source/payload cache is not
yet a complete lock of rolling binary build dependencies.
No command here opens or writes a physical target disk.
On a new build host, make init-test installs QEMU's system emulator into the
project-local Void environment before make boot-test uses it.
| Output | Meaning |
|---|---|
out/kernel/boot/kernel_2712.img |
Pi 5 kernel with boot-critical drivers built in |
out/kernel/usr/lib/modules/ |
Matching optional drivers |
out/fds-initramfs.img |
Uncompressed default initramfs; a symlink to a versioned build |
out/initramfs/initramfs.cpio* |
Uncompressed, gzip, legacy-LZ4 and Zstandard variants |
out/rootfs-aarch64.tar |
Configured userspace archive with target ownership and capabilities |
out/fds-system-cli.img |
Whole GPT cartridge image, containing an EROFS FDS_SYSTEM partition |
out/fds-boot.img |
512 MiB FAT32 partition image, labeled FDS_BOOT; not a whole NVMe disk |
out/boot-volume/manifest.json |
Boot image hash, firmware input and every boot file hash |
out/m4-vm-latest/ |
Logs and exact inputs from the last passing full boot matrix |
make internal-image combines BOOT, independent RECOVERY and INTERNAL settings
into out/fds-internal.img; see Internal storage for the
full procedure. The FAT partition image alone is not that complete disk layout.
Use the media tools for confirmed removable-cartridge writes.
What stage0 does
The initial filesystem contains static-musl stage0 and Dasung executables,
configuration, the monitor's EDID, mountpoint directories and /dev/console.
There is no shell, BusyBox, Python, glibc, or udev in it. Stage0 mounts proc, sysfs
and devtmpfs itself and binds its kernel-event socket before scanning devices.
If a single SYSTEM partition is present, stage0 verifies its block-device identity, mounts EROFS read-only, and checks the FDS identity and native init executables. It stops and reaps the early Dasung process before the base service starts, moves the kernel filesystems into the new root, removes the old in-memory root, and executes the s6 launcher. It refuses this path outside root PID 1 on ramfs/tmpfs.
Without SYSTEM, the console displays a missing-media prompt and keeps processing device events. Inserting media resumes boot without rebooting or polling sleeps. When more than one matching partition is visible, stage0 refuses to choose one. Its waiting console accepts:
list Show the discovered kernel partition identities
rescan Repeat discovery immediately
recovery Select FDS_RECOVERY instead of FDS_SYSTEM
reboot Reboot from early userspace
poweroff Power off from early userspace
An invalid filesystem or incomplete FDS root remains at the prompt. list is a
diagnostic view and can show technical device paths; physical bay labels arrive
with the cartridge daemon. Version 1 uses explicit recovery rather than an
interactive choice between multiple SYSTEMs. Detection applies to devices visible
at selection time; a cartridge inserted after root handoff cannot replace root.
Pi display and development output
image/pi5/config.txt selects the Pi 5 kernel, initramfs, external PCIe and VC4
KMS, disables HDMI audio, and avoids automatic camera/DSI setup. It does not
overclock the Pi or PCIe link. The pinned Pi kernel retains 16 KiB pages and
disables the CH341 SPI driver required by the Dasung protection policy.
The production command line uses the display console and quiet kernel output.
It loads the Paperlike 13K's recorded EDID from the initramfs before SYSTEM exists.
The unqualified drm.edid_firmware setting applies this EDID to connected DRM
outputs: this image is intended for the user's dedicated Dasung display. The
actual adapter, connector, mode acceptance and picture still need Pi validation.
Early USB control and the later base daemon share the same monitor identity.
For serial diagnosis, build:
make boot-volume BOOT_MODE=development
This replaces the convenience output link with a separate development build;
previous versioned directories remain. Development enables kernel/daemon output
and makes the Pi 5 ttyAMA10 debug UART the primary userspace console. That is
the Pi 5 debug connector, not an assumption about the 40-pin GPIO UART. Rebuild
with BOOT_MODE=production to restore the display-console configuration.
fds.boot=recovery on the kernel command line selects FDS_RECOVERY immediately.
fds.emulator=1 is reserved for the workstation emulator:
the SYSTEM loader requires QEMU virt and its fixed xHCI controller before
enabling the twelve virtual bay mappings. Default Pi boot is unchanged.
fds.debug=1 exposes the early controller's diagnostics. Duplicate or unknown
fds.* options fail clearly rather than being silently ignored.
What the automated test proves
make boot-test appends a test-only checker to a copy of the exported rootfs;
the original stage-2 script and compiled service graph still run. It checks:
- All four initramfs formats reach native s6 on read-only EROFS.
- Missing SYSTEM waits; a virtual USB insertion resumes boot.
- Two SYSTEM partitions remain unselected; the console can enter recovery.
- Explicit recovery mode selects RECOVERY even when SYSTEM is also present.
- Invalid filesystems and foreign OS roots are refused; recovery remains usable.
- Kernel page size, root ownership, ping capability, temporary filesystems, single Dasung ownership, service start/restart/stop and orderly power-off.
- Input disk hashes remain unchanged; the VM has no network or host-device access.
QEMU uses its max ARM CPU because the Pi kernel needs 16 KiB page support;
the earlier M2 Cortex-A72 fixture cannot run this kernel. These are compatibility
and behavior checks, not Pi performance measurements. Test RECOVERY is a relabeled
fixture for selection; the independent recovery product is tracked separately.
Reference material: Pi kernel builds, boot configuration, Pi UARTs, and Linux initramfs.
Use the ordinary FDS console
After building the CLI rootfs, initramfs and SYSTEM image:
make console-vm
The ARM virtual machine boots the real stage0 and read-only SYSTEM image. At
FDS> you are the ordinary fds user (UID 1000), with a temporary writable home.
Try fds info, fds inspect /FDS/CARTRIDGE.TOML, and fds boot-profile.
The console deliberately uses local autologin; both account passwords are locked.
Use fds poweroff for an orderly shutdown through native s6. Enter exit to
restart the console. Press Ctrl-a, then x to close QEMU immediately.
Closing QEMU this way ends the test immediately; it is not a graceful-shutdown test.
No host USB devices or physical disks are attached to this VM.
Run make console-test for automated console/readiness checks and
make performance-test for the software optimization comparison. Read
M5 validation and measurement boundaries
before interpreting VM timing as hardware evidence.