Table of Contents
include_toc
| include_toc |
|---|
| true |
M2: native s6 init and the ARM development VM
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 · Rootfs build · Services
M2 adds the system's real init path. The kernel enters the generated execline
launcher at /sbin/init; that immediately executes s6-linux-init, which prepares
/run and replaces itself with s6-svscan. The supervisor remains
PID 1. Bash is used for some stage-2 configuration tasks, as an ordinary child
process. No shell loop, systemd, runit, or BusyBox owns PID 1.
You can boot and inspect this system on the x86_64 workstation using a complete ARM QEMU machine. This is a generic development VM, not a Raspberry Pi image. It does not test Pi firmware, a cartridge boot path, or the physical monitor.
Build and verify
First complete the build-host setup and the
rootfs prerequisites. M2 additionally uses
the Arch e2fsprogs and libarchive packages to create an ext4 VM disk directly
from the tar, without mounting it or requiring root:
sudo pacman -S --needed e2fsprogs libarchive
make rootfs PROFILE=cli
make rootfs-test
make init-test
make init-test installs qemu-system-aarch64 inside the project-local Void build
container when missing. Void packages its emulator with display, audio, and other
libraries, even though this test uses only a serial console. Those dependencies
stay in the build container; they do not become target packages or host services.
The test also downloads a signed generic ARM kernel, pinned by version and SHA-256
in config/vm-test.conf. Its AHCI, ext4, serial console and PCI drivers are built
in and devtmpfs is automounted by the kernel, so no test initramfs or replacement stage 0 is needed. The kernel package is
approximately 161 MB; only its boot files are extracted. Its module collection is
not installed into FDS. The separate M4 boot test uses the actual
FDS Pi kernel and its initramfs-to-EROFS handoff.
The VM uses software CPU emulation, 1 GiB of RAM, two virtual CPUs, no network, and no host USB, display, filesystem sharing, or block-device passthrough. Its root filesystem is mounted read-only. QEMU discards any block changes in a temporary disk overlay, preserving the generated test disk.
Successful output includes:
FDS_M2_PID1: /usr/bin/s6-svscan
FDS_M2_FILESYSTEM: read-only root, writable tmpfs, root ownership and capabilities
FDS_M2_BOOT: getty, eudev and Dasung supervised without a monitor
FDS_M2_SERVICE: s6-rc start, echo, supervised restart, stop and start passed
FDS_M2_PASS
PASS: M2 ARM boot, native s6 PID 1, service control, and orderly power-off
The test must finish within 180 seconds. This is a failure deadline, not a boot performance target. A panic, failed assertion, missing marker, timeout, or missing power-off message makes the command fail. Retained logs explain the result.
Open a real booted ARM shell
After make init-test succeeds:
make vm
The same guest checks run, then the VM opens a temporary root shell on its serial console. Try:
readlink /proc/1/exe
findmnt /
findmnt /run
s6-rc -l /run/s6-rc -a list
s6-svstat /run/service/dasungd
dasungd status
The rootfs's ordinary getty still requires authentication and root remains locked.
The VM hook stops getty before opening its shell so they do not compete for the
serial console; s6-svstat therefore reports getty down during that shell session.
The password-free shell exists only in the disposable VM test overlay, when
make vm explicitly requests it. The checker and shell hook do not ship in the
normal rootfs archive. Type exit to request orderly VM power-off. Ctrl+C stops
the emulator immediately if the guest is stuck; it does not shut down your host.
The shell's /run, /tmp, /var/tmp, and /var/log writes disappear at power-off.
Changes to /etc or /usr fail because SYSTEM is read-only. Rebuild the rootfs
and rerun make init-test after changing packages or init configuration; make vm
otherwise boots the previous successful test disk.
Control the test service
The test-echo service is an actual Unix-socket echo server, supervised by s6.
It is included in the service database but excluded from the normal boot bundle.
In the VM shell:
s6-rc -l /run/s6-rc -u change test-echo
s6-svstat -o up,ready,pid /run/service/test-echo
printf 'hello from ARM\n' | s6-ipcclient /run/fds-test/echo.sock s6-ioconnect -t 3000
s6-svc -wR -T 5000 -r /run/service/test-echo
s6-rc -l /run/s6-rc -d change test-echo
Its socket is root-only, under /run/fds-test with mode 0700. The server sends an
actual readiness notification when it is listening. The automated test checks
the reply, confirms the PID changes on restart, stops the service, and starts it
again. No arbitrary boot delay substitutes for readiness.
What starts at boot
| Component | Role and dependencies |
|---|---|
| Native stage 1 | Consume the kernel-provided /dev, mount /run; start s6 supervision and the catch-all logger |
runtime-fs |
Mount proc, sysfs, devpts and volatile temporary/log filesystems |
hostname |
Apply the image's /etc/hostname |
console |
Create volatile login accounting files after runtime mounts |
getty |
Offer a login on /dev/console, after console and hostname setup |
eudevd |
Process device events; readiness requires a successful control request |
udev-trigger |
Request initial subsystem and device events after eudev readiness |
dasungd-runtime, dasungd-log, dasungd |
Prepare private state/log paths and supervise the base monitor controller |
Console startup does not depend on eudev enumeration, a monitor connection, the
network, or a cartridge scan. No global udevadm settle is used. The eudev package
has no native s6 notification, so s6-notifyoncheck performs a bounded check of
its control channel. It signals readiness only after a successful response.
Cartridge discovery, the FDS CLI, desktop activation and on-demand Ethernet were added after the original M2 milestone. The current image includes their real implementations; see Services, Cartridges and Desktop. This page focuses on the native init mechanism and its generic test fixture. SSH remains outside the default boot bundle.
Files and build-time work
| Location | Meaning |
|---|---|
packages/fds-init/ |
Init skeleton, runtime mount/accounting helpers, and package template |
s6/source/ |
Complete current service graph, split between init, Dasung and cartridge/desktop packages |
/etc/s6-linux-init/current/ |
Generated native init environment and stage scripts in the image |
/etc/s6-rc/compiled/ |
Compiled service database, produced during image construction |
/run/service/, /run/s6-rc/ |
Writable supervision and live service state |
/run/uncaught-logs/ |
Catch-all service log, also copied to the console |
/run/log/dasungd/ |
Rotating monitor-controller log |
out/m2-vm-latest/serial.log |
Last successful full ARM boot test |
out/m2-vm-latest/rootfs.ext4 |
Disposable test disk; not a Pi or SYSTEM cartridge image |
s6-linux-init-maker and s6-rc-compile run during the rootfs build under ARM
emulation. Boot only reads their output. The VM test preserves that exact compiled
database. Its only init hook runs the original stage-2 script to completion, then
runs the checker as a child process. Normal out/rootfs-aarch64.tar contains
neither the checker nor the development-shell hook.
The s6-generated template contains FIFOs. Archive validation permits them only
inside its run-image directory; those templates are copied into writable /run
at boot. Before entering /sbin/init, the kernel or later stage 0 must provide
a mounted devtmpfs at /dev. Stage 1 deliberately does not mount it twice.
Services never place their live FIFOs or status files on read-only SYSTEM.
M10 adds cartridge-aware preparation before s6-rc stops the remaining services.
Its native shutdown hook stays alive if DATA cannot be verified and unmounted.
s6-linux-init-shutdownd still performs final process cleanup and the kernel
power action. See Shutdown and reboot for usage, blocked-request
recovery, and the current M10 acceptance status.
Troubleshooting
make vmasks you to runmake init-test: no successful VM disk has been published yet. Build the rootfs, then run the test.- Kernel pin/hash failure: do not substitute an unverified kernel. The exact configured package must remain available or be deliberately updated and retested.
- Disk creation reports missing tar support: use an
e2fsprogsbuild with libarchive support and installlibarchive. No loop mount or sudo fallback is used. - No guest success marker: read
out/logs/init-checks.logand the printedout/m2-vm.*directory'sserial.log. Failed test workspaces are retained. - Root login is denied on the ordinary getty: this is expected with the locked base accounts. Use the explicit development VM shell, not a default password.
- Dasung says disconnected: the VM intentionally has no physical monitor. Use Dasung integration for its eventual hardware validation.
Upstream references: s6-linux-init, init generation, s6-rc initialization, and ext4 creation.
FDS/OS
Start here
Use the computer
- Use cartridges and run programs
- DATA and persistent files
- WindowMaker and FDS Control
- Dasung Paperlike display
Install and maintain
- Flash disk images
- Internal storage and machine settings
- Pi 5 EEPROM configuration
- Recovery and rollback
- Verify a release
- Reclaim build space
- Troubleshooting
Build and contribute
Home · All pages · Edit the wiki · Source repository
Maintained directly in the fds-os.wiki repository. Historical acceptance applies only to the source and artifacts identified in each record.