update docs
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
# M0: Arch Linux x86_64 build host
|
||||
|
||||
Development reference and historical context. For current operating instructions, use the [user manual](../README.md). Acceptance applies only to the source and artifacts identified in each record.
|
||||
|
||||
|
||||
[Documentation index](README.md) · [First build](getting-started.md) · [Troubleshooting](troubleshooting.md)
|
||||
|
||||
This is the technical reference for the build foundation used by later milestones.
|
||||
The [rootfs guide](rootfs.md) adds assembly, Python and isolated ARM execution requirements. If you are
|
||||
setting up the repository for the first time, follow [Your first build](getting-started.md)
|
||||
for an ordered walkthrough with expected output. For editing, rebuilding, and
|
||||
configuration changes after setup, use [Development](development.md).
|
||||
|
||||
## Scope and pinned inputs
|
||||
|
||||
M0 validates the cross-build environment. The scoped [Dasung integration](dasung.md)
|
||||
adds a controller package and service definitions without implementing a full OS.
|
||||
M1 adds the configured FDS rootfs; M2 adds native init and the generic ARM VM.
|
||||
M3 adds static FDS tools. M4 cross-builds the Pi kernel and creates initramfs,
|
||||
SYSTEM GPT/EROFS and a FAT32 boot partition; see [Boot images](boot.md).
|
||||
M6 adds cartridge management and M7 adds writable DATA. M8 adds the optional
|
||||
WindowMaker stack and on-demand Ethernet. M12 adds the [complete internal disk](internal-storage.md),
|
||||
independent recovery and persistent machine settings. The
|
||||
[signature tools](releases.md) have passed acceptance; the
|
||||
[frozen-input workflow](reproducible-builds.md) and signed local 0.1.0 release
|
||||
have passed two complete offline builds and artifact/archive verification. The [desktop guide](desktop.md) explains the
|
||||
new dependencies and the development image used for virtual display tests.
|
||||
See [Native init](init.md) for the additional test dependencies. An ARM host
|
||||
and a connected Pi are not required.
|
||||
|
||||
| Input | Pin |
|
||||
| --- | --- |
|
||||
| void-packages | Git submodule and `VOID_PACKAGES_COMMIT`: `02a3cbc132c3c4a3a9d59e9b98f517af5dd11cd1` |
|
||||
| Static XBPS host tools | Versioned `0.60.4_1.x86_64-musl` URL and a SHA-256 digest stored in this repository |
|
||||
| Rust | `rust-toolchain.toml`: 1.98.0, minimal profile, rustfmt |
|
||||
| Rust target | `aarch64-unknown-linux-musl` |
|
||||
| Rust crate dependencies | Smoketest has none; all workspace dependencies, including shared Clap CLI parsing, are pinned in `Cargo.lock`, fetched at bootstrap, and built with `--locked --offline` |
|
||||
| XBPS test package | `srcpkgs/hello/template` in the pinned Void tree: GNU hello 2.12.3_1 |
|
||||
| Pi kernel | `packages/fds-kernel/template`: 6.12.87, pinned Raspberry Pi source archive and FDS config delta |
|
||||
| Pi firmware | `config/pi-firmware.conf`: signed 20260715_1 package with a pinned SHA-256 |
|
||||
|
||||
The musl ABI of the static host tools does not determine the target ABI. Scripts
|
||||
explicitly use `XBPS_ARCH=x86_64` for the glibc build container, then run
|
||||
`./xbps-src -a aarch64 pkg hello` to build the ARM glibc package. Local ARM package
|
||||
indexing also explicitly sets `XBPS_ARCH=aarch64`.
|
||||
|
||||
## Generic Linux workstation tools and desktop additions
|
||||
|
||||
`make workstation` builds native `fds-cartridge` and `fds-emulator`. Runtime
|
||||
requirements are QEMU, erofs-utils, bubblewrap and native XBPS with a prepared
|
||||
Void source checkout for software creation. `fds-cartridge` invokes xbps-src,
|
||||
installs runtime dependencies and creates direct EROFS trees. The Rust tar reader
|
||||
and xz utility remain for legacy cartridges and package/source archives. See
|
||||
[the current workstation guide](../workstation.md).
|
||||
|
||||
The target `fds-control` panel uses x11rb 0.13.2's pure-Rust core X11 connection.
|
||||
It adds no shared GUI toolkit or background service. Its protocol, hostname and
|
||||
OS-access dependencies are locked and included in Rust license notices. Both
|
||||
the panel and foreground launcher are packaged in fds-cli as static ARM binaries.
|
||||
See [the revision rationale](current-revision.md).
|
||||
|
||||
## Host dependencies
|
||||
|
||||
Run as an ordinary user on x86_64 Arch Linux with unprivileged user namespaces.
|
||||
Rootfs construction now requires Linux 6.7+ with namespaced `binfmt_misc` support.
|
||||
The M5 build uses a private handler and static QEMU for child execution; it does
|
||||
not register an ARM interpreter in the workstation's global registry.
|
||||
The checkout path must not contain whitespace, a limitation of upstream
|
||||
xbps-src. Allow several GB of disk space and provide a network connection.
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Alternatively, run `./tools/bootstrap-host --install-deps`. Only this explicit
|
||||
option invokes sudo/pacman. Default `make bootstrap` checks dependencies and
|
||||
exits nonzero when one is missing, without installing host system packages.
|
||||
|
||||
Dependency rationale:
|
||||
|
||||
- bash, coreutils, findutils, diffutils, grep, sed, gawk, and util-linux provide
|
||||
the build scripts and upstream build system with their required shell tools.
|
||||
- git pins upstream source; curl and CA certificates download HTTPS inputs.
|
||||
- tar, xz, gzip, and zstd extract archives and XBPS packages.
|
||||
- file and binutils inspect ELF artifacts; make provides the build entry points.
|
||||
- bubblewrap runs the build container as an ordinary user.
|
||||
- rustup installs the pinned Rust toolchain and target. rustfmt checks source
|
||||
formatting and is not a runtime dependency.
|
||||
|
||||
Rust's bundled `rust-lld` and target-provided static musl/CRT are sufficient for
|
||||
the current pure-Rust smoketest. No Zig, Docker, OpenSSL crate, or additional
|
||||
musl runtime is required. The imported Dasung controller bundles libusb and uses a Void musl C cross
|
||||
compiler inside the container; see [its dependency rationale](dasung.md#dependencies-and-source-provenance).
|
||||
Glibc C libraries cannot simply be reused in static-musl binaries.
|
||||
|
||||
## Exact commands
|
||||
|
||||
Run sequentially from the repository root:
|
||||
|
||||
```sh
|
||||
make bootstrap
|
||||
make smoke-test
|
||||
make check
|
||||
```
|
||||
|
||||
Bootstrap initializes the pinned submodule, verifies and extracts XBPS, checks
|
||||
the tools' x86_64 static ELF properties, installs the pinned Rust toolchain and
|
||||
target, fetches the locked workspace crates, copies `config/xbps-src.conf` into the local Void checkout, then runs the
|
||||
equivalent of:
|
||||
|
||||
```sh
|
||||
export PATH="$PWD/.host/xbps/usr/bin:$PATH"
|
||||
export XBPS_ARCH=x86_64
|
||||
cd vendor/void-packages
|
||||
./xbps-src -A x86_64 binary-bootstrap
|
||||
```
|
||||
|
||||
`binary-bootstrap` installs upstream **base-chroot** as a compilation environment.
|
||||
It is separate from the FDS `fds-base` target rootfs built in M1. Builds run through
|
||||
bubblewrap without starting Void services on Arch. Repeated bootstrap reuses the
|
||||
masterdir and verified downloads. The script checks the container architecture,
|
||||
installed base-chroot package, and execution of GCC inside the container.
|
||||
|
||||
To reproduce the two builds individually from the repository root:
|
||||
|
||||
```sh
|
||||
./tools/cargo-build --locked --offline --release \
|
||||
--target aarch64-unknown-linux-musl -p fds-smoketest
|
||||
./tools/build-package hello
|
||||
```
|
||||
|
||||
The latter command sets the local XBPS PATH, checks the Void pin, and executes
|
||||
this command within the submodule:
|
||||
|
||||
```sh
|
||||
./xbps-src -a aarch64 pkg hello
|
||||
```
|
||||
|
||||
xbps-src installs the aarch64 GNU cross toolchain that runs on x86_64, together
|
||||
with the target glibc sysroot. No Pi compilation is needed. The pinned template's
|
||||
checksum verifies the package source archive.
|
||||
|
||||
## Validation
|
||||
|
||||
```sh
|
||||
file target/aarch64-unknown-linux-musl/release/fds-smoketest
|
||||
readelf -hW target/aarch64-unknown-linux-musl/release/fds-smoketest
|
||||
readelf -lW target/aarch64-unknown-linux-musl/release/fds-smoketest
|
||||
readelf -dW target/aarch64-unknown-linux-musl/release/fds-smoketest
|
||||
readelf -VW target/aarch64-unknown-linux-musl/release/fds-smoketest
|
||||
ldd target/aarch64-unknown-linux-musl/release/fds-smoketest
|
||||
```
|
||||
|
||||
Rust acceptance requires ELF64, little endian, AArch64, executable type EXEC/DYN,
|
||||
static linkage reported by `file`, no `PT_INTERP`, no `DT_NEEDED`, and no
|
||||
`GLIBC_*` version requirements. Static PIE is also acceptable. The pinned Rust
|
||||
target, self-contained linking configuration, and compile-time target checks
|
||||
establish musl provenance; an ELF's static label alone does not identify its libc.
|
||||
|
||||
`ldd` is supplemental diagnostic output. A static executable normally produces
|
||||
`not a dynamic executable` with exit status 1. **An x86_64 host's ldd alone cannot
|
||||
prove that an ARM executable is static.**
|
||||
|
||||
XBPS validation checks architecture=aarch64 in the local package index, then
|
||||
extracts `usr/bin/hello` from the generated package. It requires AArch64,
|
||||
`/lib/ld-linux-aarch64.so.1`, and `libc.so.6`. An architecture suffix in a package
|
||||
filename is not sufficient evidence.
|
||||
|
||||
`make check` verifies rejection of the wrong architecture, dynamic executables
|
||||
passed as static, a static-musl executable passed as a glibc package, non-ELF
|
||||
input, missing artifacts, invalid arguments, Void pin drift, and modified
|
||||
upstream files. It also tests overlay protection and runs rustfmt. Pipelines
|
||||
enable pipefail so `tee` cannot hide a failed build.
|
||||
|
||||
Optionally install `sudo pacman -S --needed qemu-user` to execute the ARM Rust
|
||||
binary during smoke-test and compare its output. When qemu-aarch64 is absent,
|
||||
the script explicitly reports SKIP. M0's required acceptance is actual
|
||||
cross-compilation plus ELF/package inspection. Static inspection is not an ARM
|
||||
runtime or Pi boot test.
|
||||
|
||||
## Inputs, caches, and overlays
|
||||
|
||||
Use `make clean-preview` followed by `make clean` when repeated builds and VM
|
||||
tests accumulate. [Cleanup](cleanup.md) explains the retained current images,
|
||||
release/input archives and caches. Full image builds and VM suites need tens of
|
||||
GiB per working tree, beyond the initial M0 smoke test's requirements.
|
||||
|
||||
- `.host/xbps/`: project-local host tools, not installed into `/usr`.
|
||||
- `vendor/void-packages/masterdir-x86_64/`: glibc build container.
|
||||
- `vendor/void-packages/hostdir/`: download caches, cross packages, and build output.
|
||||
- `out/packages/`: exported aarch64 test package and its repository index.
|
||||
- `out/manifests/void-build-packages.txt`: packages remaining installed after the
|
||||
build. Cross toolchains and temporary dependencies removed by xbps-src remain
|
||||
traceable through cache digests and build logs.
|
||||
- `out/manifests/void-package-inputs.sha256`: digests of cached `.xbps` inputs.
|
||||
- `out/manifests/artifacts.sha256`: validation artifact digests.
|
||||
- `out/logs/`: actual command logs, including logs from failed attempts.
|
||||
|
||||
Place FDS package overlays at `packages/fds-*/template`. `tools/prepare-void`
|
||||
copies only directories containing a template and refuses to replace tracked
|
||||
upstream packages. These copies are visible inside the build container. Base,
|
||||
base-files, init, CLI, kernel and Dasung overlays are active; future directories
|
||||
without templates remain inactive.
|
||||
|
||||
If an overlay changes and preparation reports a stale copy, inspect and preserve
|
||||
any unique edits before moving the specific generated copy out of `srcpkgs/` and
|
||||
retrying. Modified upstream tracked files cause immediate failure. Conflicting
|
||||
local build configuration also causes failure and must be reconciled explicitly.
|
||||
See [configuration and overlay troubleshooting](troubleshooting.md#configuration-or-overlay-conflict)
|
||||
for the procedure.
|
||||
|
||||
Updating Void requires an explicit change to both the submodule gitlink and
|
||||
`VOID_PACKAGES_COMMIT`, followed by validation and a commit containing both.
|
||||
Do not fetch master and silently change the pin. Replacing the static host XBPS
|
||||
archive also requires updating both its versioned URL and checksum.
|
||||
|
||||
## Known limitations
|
||||
|
||||
1. Source templates, Rust, and XBPS tools are pinned; **the complete Void binary
|
||||
repository is not snapshotted**. Initial bootstrap, xbps-src build-container
|
||||
updates, and missing build dependencies still use signed rolling repositories.
|
||||
Cached inputs, version inventories, and digests support auditing but cannot
|
||||
guarantee future upstream retention. M12 preserves the exact selected
|
||||
packages, sources and build tools through the accepted
|
||||
[snapshot and offline workflow](reproducible-builds.md). Its two fresh builds
|
||||
produced 27 matching artifacts. This freezes the release inputs, not the
|
||||
entire rolling Void repository; the original M0 check alone does not
|
||||
establish reproducibility.
|
||||
2. Bootstrap supports x86_64 Arch Linux. Other host distributions and ARM hosts
|
||||
have not been validated. Unprivileged user namespaces must be available.
|
||||
3. M4 tests the actual Pi kernel and initramfs-to-EROFS handoff in a generic ARM
|
||||
VM. This does not emulate Pi firmware, RP1, physical bays or the display.
|
||||
Media burning and physical boot-performance measurements remain separate work.
|
||||
4. `opt-level=z` is the plan's initial setting, not a proven fastest setting.
|
||||
Compare optimization levels later using real programs and hardware.
|
||||
5. During the initial upstream bootstrap, bubblewrap's mounted `/tmp` produced
|
||||
`rm: cannot remove '//tmp': Device or resource busy` in the cleanup phase.
|
||||
Upstream returned success; the subsequent container execution, cross build,
|
||||
and public bootstrap command passed. The upstream source was left unchanged.
|
||||
|
||||
## Upstream references
|
||||
|
||||
- [Pinned Void xbps-src usage and foreign host documentation](https://github.com/void-linux/void-packages/blob/02a3cbc132c3c4a3a9d59e9b98f517af5dd11cd1/README.md)
|
||||
- [Pinned aarch64 cross profile](https://github.com/void-linux/void-packages/blob/02a3cbc132c3c4a3a9d59e9b98f517af5dd11cd1/common/cross-profiles/aarch64.sh)
|
||||
- [Void static XBPS](https://docs.voidlinux.org/xbps/troubleshooting/static.html)
|
||||
- [Official static tool SHA-256 checksums](https://repo-default.voidlinux.org/static/sha256sums.txt)
|
||||
- [Rust aarch64-unknown-linux-musl](https://doc.rust-lang.org/rustc/platform-support/aarch64-unknown-linux-musl.html)
|
||||
- [Rust self-contained linking](https://doc.rust-lang.org/rustc/codegen-options/index.html#link-self-contained)
|
||||
Reference in New Issue
Block a user