Files
fds-os/docs/developer/getting-started.md
T
2026-09-22 13:23:34 +08:00

8.8 KiB

Your first build

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 · Troubleshooting

This walkthrough takes you from an FDS Git checkout to two verified ARM Linux artifacts. It explains the output as you go. You do not need a Raspberry Pi.

At the end you will have a small Rust program built with static musl and GNU hello packaged for aarch64 glibc. This proves that the workstation can build the two kinds of software FDS/OS needs. It does not produce a bootable OS image.

1. Check the machine and checkout

Use an x86_64 Arch Linux workstation as a normal user. Check it with:

uname -m
cat /etc/os-release
id -u

Expect x86_64, ID=arch, and a user ID other than 0. The bootstrap script currently rejects other host platforms and root execution.

Enter your FDS checkout. For the existing development workspace:

cd /home/felis/source/fds
pwd
git status --short

On another workstation, substitute its checkout directory. It must contain Makefile, Cargo.toml, tools/, .gitmodules, and Git metadata. Avoid spaces in the path. There is no configured public remote in this workspace; obtain a Git checkout from the project owner rather than using an invented clone URL.

You need HTTPS access to GitHub, Void repositories, Rust distribution servers, and package source hosts. Initial downloads total hundreds of MB. Plan for several GB of free disk space; the verified workstation used roughly 1.6 GB for the Void masterdir and 455 MB for its hostdir cache, before Rustup and other outputs. These are observations, not fixed requirements or a build-time promise.

df -h .

2. Install host prerequisites

On an otherwise maintained Arch installation, install the required packages:

sudo pacman -S --needed bash coreutils binutils git curl make file tar xz gzip zstd \
  bubblewrap rustup ca-certificates findutils diffutils grep sed gawk util-linux

This is the host package installation step. Subsequent build commands run as your normal user. The alternative ./tools/bootstrap-host --install-deps runs the same package installation and then continues bootstrap; choose one route.

The dependency reference explains why each package is needed. This project uses Rustup to select its pinned Rust compiler, not an arbitrary system Rust version. If pacman reports an existing Rust package conflict, resolve the host package choice before continuing; do not force file replacement.

Check that bubblewrap can create a user namespace:

bwrap --ro-bind / / --unshare-user --uid 0 --gid 0 true

Success produces no output and exits normally. If it fails, use Troubleshooting. This is a host capability requirement, not something a Pi can fix.

3. Prepare the build environment

From the repository root:

make bootstrap

This performs these steps:

  1. Initializes vendor/void-packages at the recorded Git commit.
  2. Downloads the pinned static XBPS archive, verifies its SHA-256, and extracts the host tools into .host/xbps/.
  3. Copies the checked-in Void build configuration into the local upstream checkout.
  4. Installs Rust 1.98.0, rustfmt, and aarch64-unknown-linux-musl through Rustup.
  5. Fetches the locked workspace crates needed for Cargo to resolve the Dasung member, including when building the dependency-free smoketest offline.
  6. Creates the x86_64 glibc Void build container and verifies that GCC runs inside it.

The Void build container supplies compilers and package tools; it is not the future FDS root filesystem. Rustup changes your user toolchain installation. XBPS host tools stay inside this repository, and no Pi storage is written.

The final success marker is:

PASS: M0 host bootstrap; run make smoke-test to build both aarch64 artifacts

The command saves its output in out/logs/bootstrap.log. Re-running bootstrap reuses the checkout and downloads, but still checks their pins and integrity. If it exits nonzero, stop here and resolve that failure before running smoke-test.

4. Cross-build both artifacts

make smoke-test

First Cargo builds rust/fds-smoketest for ARM, using the static musl libraries and linker bundled with the Rust toolchain. Then xbps-src cross-compiles GNU hello and packages it for aarch64 glibc. The first package build downloads the cross compiler, target libraries, and build dependencies such as texinfo.

The script inspects actual ELF files and local package metadata. It checks:

Artifact Required result
Rust smoketest AArch64, static linkage, no dynamic interpreter or shared library requirement
GNU hello in the XBPS package AArch64, glibc loader and libc.so.6 dependency

A successful run contains these messages; other compiler output appears between them:

PASS: aarch64 static ELF
PASS: aarch64 glibc ELF
PASS: XBPS package hello-2.12.3_1 architecture=aarch64 (glibc)
PASS: M0 smoke test complete

Without QEMU, it also reports:

SKIP: ARM execution (optional qemu-aarch64 not installed); ELF verification passed

That skip means the ARM program was compiled and inspected, but not executed. It does not hide a failed compiler or ELF check. If QEMU is installed, execution must pass; an emulator failure is a real smoke-test failure.

5. Run the protection and formatting checks

make check

Run this after smoke-test: it expects the built Rust executable to exist. It checks that bad inputs are rejected, that the Void pin and upstream files are protected, that overlays cannot replace upstream packages, and that Rust source is formatted. Several PASS: rejects ... lines are expected; they mean the negative tests worked. The final commands include:

PASS: M0 guardrail checks complete
cargo fmt --all -- --check

Rustfmt is normally silent on success. make check does not rebuild the ARM program. After a source change, rebuild first, as described in Development.

6. Inspect what you built

ls -lh out/fds-smoketest out/packages/
file out/fds-smoketest
./tools/verify-elf out/fds-smoketest aarch64 static
sha256sum -c out/manifests/artifacts.sha256

file should include ARM aarch64 and statically linked (or static-pie linked). The checksum command should report OK for both artifacts. Hashes verify the files against this run's manifest; they are not release signatures.

For ELF details, use:

readelf -hW out/fds-smoketest
readelf -lW out/fds-smoketest
readelf -dW out/fds-smoketest

The header names AArch64. There should be no INTERP segment or NEEDED library. An x86_64 host's ldd may say not a dynamic executable and return 1; that message is expected here, but is insufficient by itself to prove a foreign ELF is static. The package guide walks through the corresponding inspection of GNU hello.

7. Optionally execute the ARM Rust program

The Arch qemu-user package provides user-mode emulation. Install it if you want to execute the ARM program on the x86_64 workstation:

sudo pacman -S --needed qemu-user
qemu-aarch64 out/fds-smoketest

Expected output:

FDS/OS M0: aarch64 static-musl OK

Because this executable is static, this command needs no ARM rootfs or glibc sysroot. Explicitly invoking qemu-aarch64 also avoids needing automatic binfmt registration. Re-running make smoke-test records its own QEMU check when the emulator is on PATH.

This executes one Linux userspace program. It does not emulate the Pi's firmware, USB bays, display, battery, or operating-system boot. QEMU execution was not performed during the initial M0 validation; see the recorded results.

8. Decide what to do next

  • To build the configured OS filesystem and try its ARM programs, follow Rootfs: make rootfs PROFILE=cli, then make rootfs-test.
  • To boot native s6 and open a development console, follow Native init and ARM VM: make init-test, then make vm.
  • To build the included Dasung monitor package, follow Dasung.
  • To edit the existing Rust program, follow Development.
  • To understand the .xbps artifact, follow Packages.
  • To understand the intended removable operating system, read Architecture and Cartridges.
  • To see when bootable images become possible, read Roadmap.

Bootstrap, smoke-test, and check complete the M0 foundation. Continue with the M1 guide for a configured rootfs archive. There is still no flashing step.