FDS/OS — Felis Data Systems Operating System
FDS/OS is an operating system project for the Felis FP-85, a planned retro portable computer built around a Raspberry Pi 5, a Dasung Paperlike 13K grayscale E-Ink display, a removable battery, and 12 USB cartridge bays.
The idea is to make the computer's software and data removable. A SYSTEM cartridge carries the operating system, a DATA cartridge carries the user's files, and PROGRAM or ENVIRONMENT cartridges add applications or select an environment such as WindowMaker. The internal NVMe holds the boot machinery, recovery environment, and machine configuration. Swapping a SYSTEM cartridge is the intended update and rollback mechanism.
The project aims to combine familiar Linux software with fast, predictable startup and shutdown. It uses the Void/XBPS package ecosystem for ordinary Linux applications, uses native s6 service management, and builds FDS-owned system tools as small, self-contained Rust executables.
What you can use today
M0–M12 software acceptance is complete, including a signed local FDS/OS 0.1.0 release. Current development also adds Linux workstation software cartridges and a QEMU emulator. These changes are separate from the frozen 0.1.0 release. Physical Pi testing is deferred; see the implementation ledger. The cross-build environment is implemented and verified on x86_64 Arch Linux. You can build and inspect ARM Linux software from your Arch machine without owning a Pi.
| Available now | What it gives you |
|---|---|
out/fds-os-0.1.0/ |
Signed local images, preserved source/build inputs and independent-build comparison; start with its README.md |
make workstation |
Native Linux fds-cartridge and fds-emulator: build xz bundles, create/verify 1+m GPT images, preview USB writes, and hotplug images into twelve virtual bays |
make bootstrap |
Project-local XBPS tools, a Void build container, and the pinned Rust toolchain |
make all / make packages |
The complete image set, or just the FDS base packages; see Complete builds |
make smoke-test |
An ARM glibc XBPS package and an ARM static-musl Rust executable, with automated checks |
make check |
Checks for invalid binaries, source pin drift, unsafe overlay replacement, and Rust formatting |
make tooling / make tooling-test |
Static ARM fds and stage0 diagnostic tools, with parsing/discovery tests |
make dasung / make dasung-test |
Static ARM monitor daemon, base XBPS package, s6 definitions, and simulated monitor tests |
make rootfs PROFILE=cli / make rootfs-test |
Configured ARM rootfs archive, emulated shell access, and archive acceptance checks |
make init-test / make vm |
Full ARM boot test, native s6 PID 1, service control, and a temporary development shell |
make kernel, make initramfs, make system-card, make boot-volume |
Pi kernel, early userspace, GPT/EROFS SYSTEM and FAT32 boot partition; see Boot images |
make boot-test |
Actual stage0 handoff, missing-media insertion, recovery and archive-format checks in an ARM VM |
make console-vm, make console-test, make performance-test |
Ordinary-user FDS console, boot tracing and measured VM optimization comparison; see M5 evidence |
make cartridge-test |
Virtual USB bay mapping, hardware recognition, metadata/mount rejection checks and safe read-only eject |
make data-test |
Writable /data, managed background programs, sustained writes, safe eject and independent ext4 checks; see DATA usage |
make rootfs PROFILE=development / make desktop-test |
WindowMaker, grayscale styling, trusted ENVIRONMENT activation, managed PROGRAM execution and on-demand Ethernet; see Desktop usage |
make media-image-test / make media-test |
SYSTEM/DATA/ENVIRONMENT creation, legacy PROGRAM compatibility, confirmed writes, readback verification and boot of a newly written SYSTEM; see Media tools |
make recovery / make recovery-test |
Separate recovery rootfs and EROFS, local maintenance console, DATA checks/repairs and replacement SYSTEM workflow; software checks passed, see Recovery |
make internal-image / make internal-test |
Complete internal GPT image and persistent bay/hardware settings; see Internal storage |
make development-test |
Native C/C++/Rust builds, debuggers, build systems, Git and Vim inside the ARM development image |
make signing / make signing-test |
Host and ARM release signing/verification tools, checked independently against OpenSSL |
make eeprom / make eeprom-test |
Reversible, verified EEPROM configuration files without applying anything to hardware; see EEPROM |
| Source pinning and input records | A fixed Void source commit plus logs and hashes of the actual build inputs |
The kernel → stage0 → SYSTEM → s6 path boots in an ARM virtual machine.
The filesystem includes native s6 init, runtime mounts, console and device
services, and Dasung supervision. The ordinary-user FDS console and boot tracing are available. M6 adds the cartridge daemon and fds bays, fds bay, fds cartridge, and
fds eject; see Cartridge usage. The complete internal NVMe image and independent recovery are implemented;
release signature tooling has passed host and ARM checks.
Frozen inputs, offline rebuilds and complete release assembly
passed two independent offline builds with all 27 artifacts identical. The local
release is at out/fds-os-0.1.0/; M12 validation
records the signing identity, verification commands and exact evidence.
M10's fds poweroff and
fds reboot have passed software validation; see Shutdown usage. The fds
tool also provides identity, boot tracing and manifest inspection; see Rust tooling. See the roadmap.
Start here
- I want to build software cartridges or try virtual insertion/removal: follow the workstation walkthrough.
- I want to understand the project: read Architecture.
- I want to try the working code: follow Your first build.
- I want to build the OS filesystem: follow Rootfs.
- I want to boot it and control services: follow Native init and ARM VM.
- I want to build the Pi boot files and SYSTEM image: follow Boot images.
- I want to use the desktop, applications or Ethernet: follow Desktop usage.
- I want to create or write a cartridge: follow Media tools.
- I want persistent bay settings and an internal NVMe image: follow Internal storage.
- SYSTEM will not boot, or DATA needs checking: follow Recovery.
- I have already built it and want to develop: use the Development guide.
- A command failed: look up its message in Troubleshooting.
- I do not know the terminology: keep the Glossary open.
The documentation index organizes the remaining guides. The master plan is the full specification, rather than the recommended starting point for learning to use the repository.
Quick start: software cartridges and emulation
On a Linux workstation, build the native tools with make workstation, then
follow the complete walkthrough to package the included
hello/report examples, assemble a cartridge, boot FDS and insert it. This tooling
uses normal Linux QEMU, EROFS and xz utilities; it does not run on the Pi.
Building the complete OS images still uses the environment below.
Quick start on Arch Linux
You need an x86_64 Arch Linux host, a regular user account with access to sudo for installing prerequisites, a network connection, and several GB of free disk space. The kernel must permit unprivileged user namespaces. A Pi, Docker, and a separate musl C compiler are not required for the current smoketest.
Use a checkout path without spaces. In the current workspace:
cd /home/felis/source/fds
On another machine, enter your own FDS checkout directory instead. Use an actual Git checkout so the pinned Void submodule can be initialized for a normal online build. A complete frozen-input snapshot instead restores the source and its bundled Void checkout for offline building; a bare source archive alone does not supply those inputs. This repository does not currently configure a public Git remote, so no public clone URL is assumed here.
Install the prerequisites once:
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
Then run these commands in order, as your regular user:
make bootstrap
make smoke-test
make check
make bootstrap downloads and prepares the build tools. make smoke-test
compiles the two ARM artifacts and verifies their architectures and library
requirements. make check exercises the validation failure cases and checks
formatting. If a command fails, stop at that step and use the linked
troubleshooting guide; a partially completed run is
not a successful build.
The first run downloads hundreds of MB of compiler and build dependencies and
may take a while on a slow connection. Later runs reuse caches, although XBPS
operations may still access the network. cargo --offline applies only to Rust
crate downloads, not to the whole pipeline.
Successful smoke-test output ends with:
PASS: aarch64 static ELF
...
PASS: XBPS package hello-2.12.3_1 architecture=aarch64 (glibc)
SKIP: ARM execution (optional qemu-aarch64 not installed); ELF verification passed
PASS: M0 smoke test complete
The QEMU line is a documented optional skip. If QEMU is installed, a runtime PASS replaces it. The first-build guide explains how to run the executable with QEMU and interpret every result.
To build the current OS filesystem and boot its development VM, continue with:
sudo pacman -S --needed python e2fsprogs libarchive lz4
make rootfs PROFILE=cli
make rootfs-test
make init-test
make vm
Python must be version 3.14 or newer. Additional emulation tools are installed
inside the project-local build container. make init-test boots ARM Linux,
checks native init and service control, and powers off. make vm repeats those
checks and opens a temporary root shell; type exit to shut it down. Nothing is
flashed to a physical disk. The VM guide explains the console,
service commands, logs, and limits in detail.
To build the complete operating-system image set and try its ordinary user console, continue from that prepared workstation:
The complete images require substantially more space than the initial smoke test: the offline diagnostic build occupied about 24 GB, before additional VM test copies. See build-space observations before preparing two independent release builds.
make all
make init-test
make boot-test
make console-vm
make all builds CLI and development SYSTEM cartridges, independent recovery
and the internal disk. make init-test prepares the full QEMU environment and
checks native init. make boot-test checks startup, missing-media recovery and
all initramfs formats. make console-vm opens the actual FDS> console.
Enter these commands inside that console:
fds info
fds bays
fds boot-profile
fds poweroff
This VM has no physical USB devices attached, so empty cartridge bays are
expected. Its home directory is temporary; use a DATA cartridge for persistent
files on the real machine. fds poweroff performs an orderly shutdown. The
boot guide explains console controls,
and the internal-storage guide covers physical
installation when the Pi hardware is ready.
Dasung monitor support
The existing Rust dasungd from the monitor troubleshooting task is integrated
as a required base-system package, with a native s6 boot service. Build it with
make dasung, then run make dasung-test. The Dasung guide
explains the exact monitor profile, dependencies, configuration, and Pi validation
still needed. M2 starts the controller under native s6 in the ARM VM; the VM has no physical monitor.
What the build produces
| Path | Contents | How to use it |
|---|---|---|
out/fds-internal.img |
Complete GPT disk with BOOT, independent RECOVERY and persistent machine-settings partitions | Use the internal installation procedure; this belongs on the internal NVMe |
out/fds-system-cli.img |
Immutable CLI SYSTEM cartridge, including base Dasung support | Build with make system-card PROFILE=cli; use the media writer to write a SYSTEM cartridge |
out/fds-system-development.img |
SYSTEM with native compilers, debugging tools and the optional desktop runtime | Build with make rootfs PROFILE=development followed by make system-card PROFILE=development |
out/fds-boot.img / out/fds-recovery.img |
Individual FAT32 BOOT and EROFS RECOVERY partition payloads | Normally use the complete internal image; these are component images, not interchangeable whole disks |
out/fds-initramfs.img |
Early boot program and base display support | Included in BOOT; four compressed/uncompressed formats are also under out/initramfs/ |
out/rootfs-aarch64.tar |
Configured ARM glibc userspace, including Dasung | Follow M1 rootfs to build, inspect, and run it |
out/m2-vm-latest/ |
Last successful ARM test disk, serial log, environment and hashes | Use make vm to boot it; see Native init |
out/fds-smoketest |
Static-musl AArch64 Rust executable | Inspect with file/readelf; optionally run with qemu-aarch64 |
out/packages/hello-2.12.3_1.aarch64.xbps |
GNU hello packaged for ARM glibc | Query or extract it with the package guide |
out/packages/aarch64-repodata |
Local package index | Lets XBPS query the exported package |
out/logs/ |
Bootstrap and build logs | Diagnose a failed or apparently stalled step |
out/manifests/ |
Package inventories and SHA-256 digests | Inspect which inputs and outputs were used |
make all produces the complete image set above in order. It prepares files and
does not write physical disks. Build and test commands share a build container;
run them sequentially. Stable paths point to the latest successful versioned
build directories. See Offline rebuilds for the
separate frozen-input and release-verification workflow.
The rootfs tar and individual binaries are not flashable Pi images. The separate VM disk boots with the generic ARM test kernel. The Rust executable is ARM code and normally cannot run directly on the x86_64 host. The XBPS package is not an Arch package and is not installed with pacman.
How the build relates to the future machine
Working today: x86_64 Arch workstation
├─ pinned Void + xbps-src + GNU cross compiler → aarch64 glibc package
└─ pinned Rust + bundled musl + rust-lld → static AArch64 executable
Pi boot path, software-tested in a VM; physical validation pending:
internal NVMe kernel/initramfs → SYSTEM cartridge → native s6 → FDS console
The first line supplies conventional Linux packages. The second supplies FDS's own control tools without a dependency on the installed glibc version. Both produce ARM code; only their library/linking strategy differs. See the architecture guide.
Where to find things
| Directory or file | Purpose today |
|---|---|
rust/fds-smoketest/, rust/dasungd/, rust/fds-common/, rust/fds-cli/, rust/fds-stage0/ |
Static-linking smoketest, monitor controller, shared contracts, CLI and early boot |
tools/ |
Bootstrap, package build, overlay preparation, and ELF checks |
config/ |
Pinned host tool download and Void build configuration |
vendor/void-packages/ |
Unmodified upstream source at the recorded commit |
tests/integration/m0-checks |
Executable validation and protection checks |
docs/ |
Tutorials, design explanations, references, and validation evidence |
packages/fds-dasungd/, s6/source/, image/base-packages.list |
Monitor package, native service definitions, and mandatory base inclusion |
packages/fds-base/, packages/fds-base-files/, packages/fds-init/ |
Base dependencies, identity, accounts, layout and native init |
packages/fds-kernel/, packages/fds-cli/, image/ |
Pi kernel delta, static CLI package and filesystem/boot builders |
profiles/ |
CLI, development and recovery package selections |
rust/fds-release/, tools/frozen-inputs, tools/assemble-release |
Signature verification, input preservation and local release assembly |
Generated .host/, target/, and out/ contents are ignored by Git. Rustup also
installs the pinned toolchain in your user account's Rustup directory. The
build reference details prerequisites, storage, and pins.
Project status and evidence
The M0 validation report records the actual build commands, results, and initial artifact hashes. QEMU execution and Pi hardware were not validated in that initial run. Later milestones measured VM boot and shutdown; physical Pi performance remains unmeasured. Source and toolchain pins are in place, and the complete frozen-input/offline release workflow is undergoing M12 acceptance. See current evidence for the distinction.
The M1 guide explains rootfs usage; M1 validation records the results. M2 usage is in Native init and ARM VM, with results in M2 validation. M3 adds static-musl FDS tooling. Work continues through M12 under AGENTS.md, with physical hardware checks deferred. Project-owned source comments, documentation, diagnostics, and development discussions use English.