Files
fds-os/docs/getting-started.md
T
2026-09-21 22:29:23 +08:00

233 lines
8.6 KiB
Markdown

# Your first build
[Documentation index](README.md) · [Troubleshooting](troubleshooting.md)
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:
```sh
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:
```sh
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.
```sh
df -h .
```
## 2. Install host prerequisites
On an otherwise maintained Arch installation, install the required packages:
```sh
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](build-host.md#host-dependencies) 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:
```sh
bwrap --ro-bind / / --unshare-user --uid 0 --gid 0 true
```
Success produces no output and exits normally. If it fails, use
[Troubleshooting](troubleshooting.md#bubblewrap-or-user-namespace-failure).
This is a host capability requirement, not something a Pi can fix.
## 3. Prepare the build environment
From the repository root:
```sh
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:
```text
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
```sh
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:
```text
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:
```text
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
```sh
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:
```text
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](development.md#edit-and-rebuild-the-rust-program).
## 6. Inspect what you built
```sh
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:
```sh
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](packages.md#inspect-the-built-package) walks through the
corresponding inspection of GNU hello.
## 7. Optionally execute the ARM Rust program
The [Arch qemu-user package](https://archlinux.org/packages/extra/x86_64/qemu-user/)
provides user-mode emulation. Install it if you want to execute the ARM program
on the x86_64 workstation:
```sh
sudo pacman -S --needed qemu-user
qemu-aarch64 out/fds-smoketest
```
Expected output:
```text
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](m0-validation.md).
## 8. Decide what to do next
- To build the configured OS filesystem and try its ARM programs, follow [Rootfs](rootfs.md): `make rootfs PROFILE=cli`, then `make rootfs-test`.
- To boot native s6 and open a development console, follow [Native init and ARM VM](init.md): `make init-test`, then `make vm`.
- To build the included Dasung monitor package, follow [Dasung](dasung.md).
- To edit the existing Rust program, follow [Development](development.md).
- To understand the `.xbps` artifact, follow [Packages](packages.md).
- To understand the intended removable operating system, read [Architecture](architecture.md) and [Cartridges](cartridges.md).
- To see when bootable images become possible, read [Roadmap](roadmap.md).
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.