FDS/OS 1.0

This commit is contained in:
2026-09-21 22:29:23 +08:00
commit 99bc3d15c5
430 changed files with 34876 additions and 0 deletions
+237
View File
@@ -0,0 +1,237 @@
# Building and using the ARM root filesystem
[Documentation index](README.md) · [First build](getting-started.md) · [Validation](m1-validation.md)
The assembler produces a configured **aarch64 glibc Linux userspace** at
`out/rootfs-aarch64.tar`. It contains GNU tools, XBPS, the s6 tools, the cartridge manager, optional desktop stack, and the Dasung
Paperlike 13K controller. You can inspect it and run its ARM programs on the build
workstation. M2 adds native s6 init, runtime mounts and getty. The tar itself has
no bootable partition table or Pi boot volume; do not flash the tar to a disk.
Follow [Native init and ARM VM](init.md) to boot it and open a development shell.
M12 also adds `make rootfs PROFILE=recovery` and `make recovery`; see
[Recovery](recovery.md) for its distinct local maintenance console and read-only
cartridge defaults. Each build preserves a profile-specific
`out/rootfs-PROFILE.tar` pointer in addition to the latest-rootfs pointer.
## 1. Prepare the workstation
Use the x86_64 Arch setup in [Your first build](getting-started.md). M0 should pass
before you build M1:
```sh
make bootstrap
make smoke-test
make check
```
M1 also needs **Python 3.14 or newer** on Arch. It inspects XBPS metadata and zstd
package archives and produces the tar using only the standard library:
```sh
sudo pacman -S --needed python
python3 --version
```
The rootfs builder installs `qemu-user-aarch64` and `util-linux` into the existing
project-local Void build container. Static QEMU executes ARM programs; util-linux
supplies namespace-local mount and capability setup. Linux 6.7+ provides a private
`binfmt_misc` registry inside the new user namespace, allowing ARM child programs
to execute without PRoot's syscall translation. Mount/setup capabilities are
dropped before package scripts run; only namespace-local file-capability support
remains. These are build tools, not additional target requirements. No host-wide
binfmt registration, sudo chroot, or host boot configuration is needed.
The Dasung musl compiler dependencies remain documented
in [Dasung integration](dasung.md#dependencies-and-source-provenance).
Allow several additional GB for package downloads, staging trees, the archive,
and retained inputs. Build commands share one Void container; run them sequentially.
## 2. Build the CLI base
From the checkout root:
```sh
make rootfs PROFILE=cli
```
The first run downloads signed Void ARM packages and may take several minutes.
Later runs reuse the download cache, rebuild the local FDS packages, and assemble
a fresh root. Success ends with:
```text
PASS: FDS rootfs built and verified: out/rootfs-aarch64.tar
```
`cli` boots to the ordinary-user FDS console and includes optional desktop and
Ethernet services. They start only when requested by the user or eligible media.
`PROFILE=development` adds native C/C++/Rust compilers, build systems, Git,
debuggers and Vim, plus virtual display diagnostics; see
[Development](development.md) and the [desktop guide](desktop.md).
Each archive embeds its profile identity. Unknown
profiles and mismatched SYSTEM image labels fail explicitly.
| Output | Purpose |
| --- | --- |
| `out/rootfs-aarch64.tar` | Exported root filesystem, with target ownership, permissions and file capabilities |
| `out/rootfs-aarch64/` | Staging tree for inspection and emulated commands; owned by your host user |
| `out/manifests/rootfs-latest/` | Exact package list, checksums, metadata, scripts and build inputs |
| `out/manifests/rootfs-latest/packages/` | Copies of every selected XBPS package and available upstream signatures |
| `out/packages/fds-base-0.1.0_1.aarch64.xbps` | Explicit base dependency metapackage |
| `out/packages/fds-base-files-0.1.0_1.aarch64.xbps` | FDS identity, accounts, defaults and layout specification |
| `out/logs/rootfs-build.log` | Package installation, configuration and acceptance output |
The first three paths are links into one retained `out/rootfs-build.*` directory.
A failed build keeps its workspace for diagnosis and does not publish a partial
archive over the last successful one. Copy the tar itself when moving the result
to another machine; copying only the link does not copy the artifact.
## 3. Inspect the result
```sh
tar -tf out/rootfs-aarch64.tar | head -40
cat out/rootfs-aarch64/etc/os-release
cat out/manifests/rootfs-latest/packages.json
(cd out/manifests/rootfs-latest && sha256sum -c rootfs.sha256 packages.sha256)
```
The default hostname is `fds`, the timezone is UTC, and the default language is
English (`en_US.UTF-8`). Account passwords are locked and no SSH server starts.
CLI and development boot to the local `fds` account (UID 1000) through autologin;
recovery has a local root maintenance console. The build shell below runs as
emulated root so it can inspect and configure the staging tree. It is separate
from the normal booted user session.
## 4. Run ARM programs on the workstation
```sh
./tools/in-rootfs out/rootfs-aarch64 /usr/bin/ls --version
./tools/in-rootfs out/rootfs-aarch64 /usr/bin/readelf --version
./tools/in-rootfs out/rootfs-aarch64 /usr/bin/xbps-query -l
./tools/in-rootfs out/rootfs-aarch64 /usr/bin/dasungd check
./tools/in-rootfs out/rootfs-aarch64 /bin/bash --login
```
Inside the shell, try `getconf GNU_LIBC_VERSION`, `locale charmap`, `ls /usr/bin`,
or `xbps-query fds-base`. Type `exit` to return to the workstation.
This runs ARM userspace on the host kernel through QEMU. It does not boot an ARM
kernel or validate Pi drivers. Bubblewrap makes the target the actual process
root, supplies minimal devices, and mounts temporary `/run` and `/tmp`. Native
emulation tools are mounted read-only under `/tmp/fds-build-host`. Physical USB
and DRM are absent, so this helper cannot control your monitor. Use it for trusted
image-build commands. Do not use
this shell to test disk formatting, mounts, power-off, or real device access.
Commands can modify the staging tree. Those changes do **not** change the exported
tar. Rebuild to get a clean staging tree and archive. Built SYSTEM images remain
read-only: change packages at image build time, not by upgrading a live SYSTEM.
For the booted target's on-demand Ethernet and DNS policy, see
[Desktop and Ethernet](desktop.md).
## 5. Run the acceptance checks
```sh
make rootfs-test
```
This verifies the archive and saved package checksums, restores a disposable
tree, and runs ARM glibc, GNU tools, a shell pipeline, locale, XBPS integrity,
Dasung configuration, and s6 database queries under QEMU. It also checks every
ELF file for the target architecture, validates archive permissions and ping
capabilities, and tests rejection of forbidden packages, unfinished configuration,
wrong ABIs, a host executable, missing boot entries, a shell init replacement,
and unsupported profiles.
The image has no BusyBox, systemd, runit, or musl runtime package. Dasung carries
its own statically linked musl and libusb. Its service database is compiled at
build time and includes the base monitor bundle. M2 boots the current graph under native s6 PID 1 in a full ARM VM. Physical
monitor recovery still requires a Pi test.
## What goes into the base
`packages/fds-base/template` owns the explicit dependency set. The assembler also
consumes `image/base-packages.list`, so the required hardware package cannot be
lost when selecting a profile.
| Package group | Reason |
| --- | --- |
| glibc, glibc-locales | GNU C runtime and compiled English UTF-8 locale |
| coreutils, binutils, findutils, diffutils, grep, sed, gawk, bash, tar, gzip, xz | GNU command-line tools, ELF inspection, scripting and archives |
| util-linux, procps-ng, shadow, kbd | Standard system, process, account and console utilities |
| e2fsprogs, dosfstools, erofs-utils | Tools for the planned ext4, FAT and EROFS media |
| eudev, kmod | Device discovery tools and module management |
| iproute2, iputils | Network inspection and configuration tools |
| pciutils, usbutils | Hardware inspection |
| ca-certificates, tzdata, xbps | TLS trust, timezones, and the package database/tools |
| skalibs, execline, s6, s6-linux-init, s6-rc | Native init, process supervision, and service dependency tools |
| fds-base-files, fds-init, fds-dasungd | FDS defaults, native init/service graph, and the mandatory monitor controller |
XBPS resolves shared libraries and other transitive dependencies. The exact
resolved set is in `packages.json`; do not mistake the direct dependency list for
the entire installed set. Planned `fds-cli` and `fds-cartridged` packages are
deliberately absent until their implementation milestones.
## Assembly details
The FDS base-files package supplies `usr/share/fds/layout.json`. The assembler
applies that manifest before XBPS extraction to create merged `/usr` links and
empty mountpoints. Upstream xbps-src reserves these links for Void's own
`base-files`; this approach keeps its tracked files and lint rules unchanged.
Remote packages are signature-checked using Void keys from the pinned checkout.
Local FDS packages are built here and are unsigned development artifacts. A
foreign-architecture XBPS transaction unpacks them; the target's own XBPS then
configures every package under QEMU. Locales, CA certificates, the udev hardware
database, the dynamic linker cache, native init environment, and the complete
s6 service database are ready before export. Certificate generation also runs as
an explicit checked step: the upstream CA package wrapper suppresses updater
errors. There is no first-boot package configuration step.
Unused upstream runit service files are excluded by the shipped XBPS `noextract`
rules. This does not replace upstream package templates or add runit to the image.
The staging directory cannot preserve arbitrary target UID/GID values as a normal
host user. Export restores ownership from the exact XBPS archive headers, applies
the util-linux `wall`/`write` tty-group and XBPS `xbps-uchroot` xbuilder-group adjustments, and gives generated
files root ownership. Namespaced Linux capabilities are converted to the portable
root-owned encoding. The archive, not the host-owned staging tree, is the authority
for installation metadata. When eventually restoring as root, use GNU tar with
`--numeric-owner --same-permissions --xattrs --xattrs-include=security.capability`.
For complete disk images and the deferred physical installation procedure, see
[Internal storage](internal-storage.md). Do not write this rootfs tar to a disk.
The rootless configuration log therefore reports group-change failures for
`wall`, `write`, and `xbps-uchroot`. These three known adjustments are applied
and checked in the exported archive. Other installation errors require investigation.
The builder also reapplies and verifies ping's `CAP_NET_RAW` with direct QEMU
inside a user namespace and checks the actual stored xattr.
Package versions, input hashes and selected archives are retained for inspection.
The Void binary repository is rolling; a fresh build later may resolve different
versions. Those records alone do not establish reproducibility. Use the
separate [frozen-input and offline rebuild workflow](reproducible-builds.md) for
release construction and consult its recorded acceptance status.
## If a build fails
Read the last error in `out/logs/rootfs-build.log`; keep the printed build-workspace
path. A package setup error is a build failure, not a reason to publish an
unconfigured filesystem. Correct the issue and run the build again; downloads
already in `out/cache/rootfs` are reused.
If you changed an overlay and receive `Stale overlay`, compare your edited
`packages/fds-*` directory with the named generated copy under
`vendor/void-packages/srcpkgs/`. Move only that generated copy out of the way and
rerun. Never discard tracked upstream changes to silence the pin check. See
[Troubleshooting](troubleshooting.md) for the existing build-container checks.
References: [Void chroot installation](https://docs.voidlinux.org/installation/guides/chroot.html),
[XBPS configuration](https://man.voidlinux.org/xbps.d.5),
[Linux binary-format handlers](https://docs.kernel.org/admin-guide/binfmt-misc.html), and
[QEMU userspace emulation](https://www.qemu.org/docs/master/user/main.html).
The rootless exporter restores ownership changes that package install scripts
cannot represent in a single-UID user namespace. This includes tty ownership for
`wall`/`write`, the xbuilder group for `xbps-uchroot`, and the utmp group for the
terminal-accounting helper. Archive checks validate these identities explicitly;
the ARM boot check also inspects the installed helper's actual group.