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

129 lines
5.8 KiB
Markdown

# M1 root filesystem validation
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) · [Build and usage](rootfs.md) · [Roadmap](roadmap.md)
Validated on **2026-09-21 (Asia/Shanghai)** on the x86_64 Arch workstation.
The archive build timestamp is `2026-09-20T16:58:35Z`. This is userspace and
archive validation, not a Pi boot or native PID 1 result.
## Artifact produced
| Item | Recorded result |
| --- | --- |
| Output | `out/rootfs-aarch64.tar` |
| Archive size | 346,705,920 bytes |
| Configured packages | 108 |
| ARM ELF paths inspected | 1,167 |
| SHA-256 | `b2f0472d49aeb1565d124bc30f250cb304dc265be4d049f1ac9e8cb533742a34` |
| Void source pin | `02a3cbc132c3c4a3a9d59e9b98f517af5dd11cd1` |
| Emulation tools | PRoot 5.2.0_1 and QEMU aarch64 userspace 11.1.1_1 |
The successful build is retained in `out/rootfs-build.Ewfkl2/`. Convenience links
point to its archive, staging root, and manifests. Future rebuilds may replace
the convenience links; this report describes the result above.
Selected package versions:
```text
fds-base-0.1.0_1
fds-base-files-0.1.0_1
fds-dasungd-0.1.0_1
glibc-2.41_1
coreutils-9.4_3
binutils-2.44_2
xbps-0.60.7_1
s6-2.15.0.0_1
s6-rc-0.6.1.1_1
```
Every selected package archive is retained with its SHA-256 in the build
directory. Remote packages were verified against Void's RSA keys; local FDS
packages are unsigned development builds. The package archives total 71,371,822
bytes, excluding signature files. This is input retention, not a complete
upstream repository snapshot or a reproducible-release claim.
## Acceptance completed
```sh
make rootfs PROFILE=cli
make rootfs-test
```
Both commands exited successfully. Checks established:
- `fds-base` selects GNU userspace, glibc, XBPS and the mandatory Dasung package.
Neither the Void `base-system` nor its `base-files` package is installed.
- Every installed package is `aarch64` or `noarch` and configured. All scanned
ELF files are little-endian 64-bit ARM. Dynamic interpreters resolve to glibc.
Dasung is statically linked and has no dynamic interpreter or shared-library
dependency. No BusyBox, systemd, runit, or musl runtime package is present.
- The target's package setup ran under QEMU. English UTF-8, CA certificates,
the udev hardware database, the dynamic linker cache, and the Dasung s6 database
were generated before export. `_uuidd` was created and root remains locked.
- ARM GNU coreutils/binutils, glibc, shell pipelines, locale lookup, XBPS queries,
package integrity checking, Dasung configuration/EDID checking, and s6 database
queries succeeded. Tests do not open a real USB or DRM device.
- Exported ownership and permissions were checked, including locked account
files, sticky temporary directories, the tty group for `wall`/`write`, the
xbuilder group for `xbps-uchroot`, and portable `CAP_NET_RAW` for ping.
- GNU tar restored the exported ping capability successfully inside a private
user namespace, verifying the archive's actual extended-attribute encoding.
- A fresh extraction of the exported archive passed the same userspace checks.
- Failure tests rejected a forbidden package, an unconfigured package, a musl
package ABI, an injected x86_64 executable, a missing Dasung boot entry, and an
unsupported image profile.
The build leaves upstream Void tracked files unchanged. The FDS layout manifest
avoids changing upstream lint rules. The tests use the exported tar rather than
trusting the original staging tree alone.
## Regression checks
The following also exited successfully after the M1 changes:
```sh
make bootstrap
make smoke-test
make check
make dasung-test
```
The Dasung rerun passed all six Rust unit tests, the serial simulator cases,
package inspection, and the s6 boot/logger/socket/restart/stop check with a
read-only root and no monitor. Its physical-hardware checks remain skipped.
The existing M0 smoke script still reports its optional host-PATH QEMU skip:
the emulator is installed only inside the project-local build container. M1's
explicit container-based ARM runtime tests passed independently.
Shell syntax checks were updated to recognize shell files by their interpreter,
so adding Python image tools does not make the older test suites parse Python
as shell. Python syntax, documentation file links, English project context,
and upstream tracked-file cleanliness were also checked.
## Emulation and rootless-build limitations addressed
The packaged PRoot version does not translate every modern syscall reliably.
The helper therefore makes the ARM filesystem the actual root with bubblewrap,
and uses direct QEMU for XBPS integrity checking and capability operations.
PRoot is used for child-process execution during package configuration and shell
sessions, not as evidence of successful ownership or capability changes.
Rootless configuration emits expected group-change failures for `wall`, `write`,
and `xbps-uchroot`. Archive generation restores their intended numeric groups
and the archive tests verify the result. Other package payload ownership comes
from the retained XBPS headers. No host user ID is exported as the target root.
## Remaining boundaries
- M2: native s6 PID 1, complete boot graph, runtime mounts and booted service control.
- M4 and later: Pi firmware/kernel/initramfs, EROFS SYSTEM image, console, and media creation.
- Hardware: monitor picture, cold-power recovery, USB hotplug under Pi boot, and 12-bay behavior.
- Performance: no boot, shutdown, or monitor readiness benchmark was measured.
The rootfs is not flashable, does not provide `fds` or a cartridge daemon, and
does not provision a login password. See [Rootfs](rootfs.md) for the working
emulated-shell workflow and the [roadmap](roadmap.md) for later acceptance gates.