Architecture
- Snapshot
- v0.2.0
- Source path
docs/architecture.md- Tree
c41b976e0362
This guide follows FlashOS from configuration and source through packages, image assembly, boot, and the first Flash session. It also shows which parts are maintained by FlashOS and which still come from Redox or other upstream projects. The presence of code elsewhere in the repository or upstream does not make it a supported FlashOS feature.
On this page
- Architectural scope
- System context
- Ownership and dependency model
- Current system layers
- Image configuration
- Build-to-image flow
- Boot-to-shell flow
- Flash integration
- Verification boundaries
- What this architecture does not imply
- Sources of truth
Architectural scope
The current FlashOS product architecture is defined by the following boundaries:
| Area | Current boundary |
|---|---|
| Product architecture | x86_64 |
| Target ABI | x86_64-unknown-redox |
| Primary environment | Text-based console interface |
| Primary user interface | Flash at /usr/bin/fsh |
| Primary evaluation platform | QEMU q35 with x86_64 UEFI firmware |
| System maturity | Pre-alpha |
The repository retains inherited build-system branches and recipes that refer to architectures other than x86_64. Their presence does not establish a FlashOS product profile, tested image, release target, or hardware-support commitment for those architectures.
The current product profiles are located under config/x86_64/. Hardware qualification is documented separately in Hardware Compatibility, while future architectural direction belongs in the Roadmap.
System context
FlashOS spans two distinct execution environments: the host-side build system and the target system contained in the generated image.
- 01Local configuration
- 02Make and container orchestration
- 03Cross-toolchain and target sysroot
- 04Cookbook recipes and package repository
- 05Installer and filesystem tooling
- 01Firmware
- 02Bootloader
- 03Kernel
- 04Drivers, schemes, and system services
- 05Console login
- 06Flash and external userspace commands
The host environment produces an image for the target environment. Host-side utilities, container dependencies, and development-only Flash integrations are not automatically part of the generated operating-system image.
Ownership and dependency model
FlashOS currently combines project-owned product components with inherited and external infrastructure. These categories must remain distinguishable.
| Category | Meaning | Examples |
|---|---|---|
| FlashOS-owned component | Source or configuration maintained as a direct FlashOS product responsibility | Image profiles, Flash, documentation, CI contracts |
| Pinned upstream component | External source fetched at a specific revision and built as part of the image | Kernel, bootloader, relibc, base services, utilities |
| Locally patched upstream component | Pinned upstream source modified by repository-maintained patches | Kernel, bootloader, installer, and login branding or policy changes |
| Inherited build infrastructure | Repository-local orchestration derived from the Redox build system and adapted for FlashOS | Root Cargo build crate, Makefile, mk/, Cookbook integration |
| Compatibility interface | A technical name that remains because the active ABI or tool still uses it | x86_64-unknown-redox, relibc, redox_installer, RedoxFS |
A local patch does not convert the complete upstream component into a FlashOS-native implementation. For example, the kernel recipe applies FlashOS-specific visible branding to a pinned Redox kernel revision, but the kernel architecture, system-call model, driver framework, and most implementation code remain upstream dependencies.
Similarly, preserving an inherited technical identifier does not determine project identity. Names such as x86_64-unknown-redox describe active compatibility contracts and must remain until the corresponding interface is replaced, not merely renamed.
Component origin and product ownership
A FlashOS-owned component does not necessarily originate entirely within the FlashOS project. Existing open-source projects may be imported or forked when they provide a suitable technical foundation.
Once adopted as part of the FlashOS user environment, such components may be substantially modified in behavior, interface, architecture, and visual design. FlashOS then assumes responsibility for the resulting product experience and for maintaining its project-specific changes.
The Redox kernel is the deliberate exception. FlashOS intends to keep the kernel close to upstream and modify or extend it only when concrete product, hardware, or platform requirements make such changes necessary.
Current system layers
Host build orchestration
The root Makefile and files under mk/ coordinate:
- local configuration resolution;
- containerized or native build execution;
- cross-toolchain provisioning;
- package fetching and compilation;
- filesystem-tool compilation;
- image assembly;
- QEMU execution.
The default local path uses Podman, while hosted image qualification uses a dedicated container workflow. Containerization isolates many host dependencies, but it is a build boundary rather than a runtime feature of FlashOS.
Cross-toolchain and target ABI
The build system targets:
x86_64-unknown-redox
The prefix stage supplies the Rust, GCC, Clang, linker, runtime-library, and sysroot components needed to compile target packages. relibc, target support libraries, and the target triple remain part of the inherited Redox compatibility boundary.
The target ABI is therefore not a FlashOS-designed ABI. Code that compiles for a general Unix-like host does not automatically compile or behave identically on the FlashOS target.
Bootloader and kernel
The bootloader and kernel are fetched through pinned recipes:
recipes/core/bootloader/recipes/core/kernel/
Both apply local patches for FlashOS-visible identity. The bootloader provides BIOS and UEFI outputs for architectures supported by its upstream recipe, but the active FlashOS product path uses the x86_64 UEFI output.
The bootloader package is a media-build dependency, not an installed root-filesystem package. The installer stages it in a temporary host directory, extracts the BIOS or UEFI bytes needed by the disk and live-media partitions, and removes the temporary tree. The kernel package similarly installs only the bootable kernel into the image; its complete image and symbol table remain in the build tree for host debugging.
The kernel provides the low-level process, memory, scheme, interrupt, and hardware-driver foundation. FlashOS does not currently maintain an independent kernel implementation.
Base system and services
The base and userutils packages provide inherited system initialization, login, and service infrastructure. The active profile supplements these packages with FlashOS-owned configuration for:
- console initialization;
- system hostname and release identity;
- login shells;
- scheme permissions;
- filesystem layout;
- development-network defaults.
Runtime drivers and services are selected through the package set and initialized by the installed system scripts. Their presence in an upstream source tree is not sufficient to classify them as active or qualified FlashOS functionality. The current base package excludes the unused redoxerd host/debug daemon and the unqualified VirtualBox guest driver; QEMU q35/UEFI remains the defined virtual-machine path.
Userspace utilities
The active image selects a small console-oriented userspace. It includes a mixture of Redox utilities, uutils-based commands, networking support, runtime libraries, and Flash. The extrautils recipe remains buildable for explicit developer use but is not selected by either image profile because no current guest setup, recovery, or QEMU contract requires its commands.
These programs remain separate processes. Flash coordinates command execution but does not reimplement every external utility included in the image.
Flash
Flash is the primary FlashOS-owned user-facing component. The base flash
package installs the fsh shell. The separately staged flash.lsp package
provides the flash-language-server protocol executable without coupling it to
the login shell. Both active profiles select that package because the frozen
Flash v1 target contract exercises the server in the exact image. No editor is
installed and the language server is not started as a service. The active
system profiles assign /usr/bin/fsh as the login shell for both configured
accounts.
Flash is a userspace process. It does not replace the kernel, system initialization, authentication service, filesystem, package manager, or external command implementations.
Image configuration
FlashOS image composition is defined by three central configuration files:
| File | Responsibility |
|---|---|
config/flashos-base.toml |
Shared TUI-oriented system foundation |
config/x86_64/flashos.toml |
Development image profile |
config/x86_64/flashos-release.toml |
Release image profile |
Shared base profile
flashos-base.toml is a standalone base configuration rather than an extension of a graphical desktop profile. It defines the common package selection, filesystem structure, scheme access, networking defaults, and sudo-group membership used by both x86_64 profiles.
The declared base package set includes:
base
kernel
libgcc
netdb
netutils
relibc
userutils
uutils
The base profile retains interfaces needed by the current console system, including framebuffer display, input, networking, audio, terminals, processes, and files. It does not grant the unprivileged account access to the Orbital scheme and does not recreate the inherited /ui compatibility path.
Product-specific profile
The development and release profiles add:
flash
flash.lsp
coreutils
They also define:
- the x86_64 filesystem size;
- the
flashoshostname; - FlashOS release identity files;
- console startup through
inputdandgetty; /usr/bin/fshas the configured login shell.
These names are the packages explicitly selected by the image manifests. The selected relibc package contains the dynamic runtime and loader aliases. Headers, static archives, and CRT objects are separated into relibc.dev, which the target build/sysroot boundary selects explicitly and the image does not install. libstdcxx is not selected because no current runtime ELF declares it as a dynamic dependency.
Cookbook still resolves supporting build dependencies. In particular, the
pinned bootloader is built for the installer's temporary media-staging path,
while redoxfs, development libraries, and kernel symbols remain outside the
shipped root filesystem. The separately staged language-server package is
selected because it owns an existing exact-image Flash v1 exercise, but it does
not add an editor or service. The image also carries no package-source
configuration because it installs no package-manager executable.
Development and release variants
The development and release profiles are required to remain identical in their general settings, package selection, and installed files. Their intentional difference is the credential model.
The development profile contains convenience credentials for local evaluation. The release profile locks direct root login and removes the development passwords. This separation is enforced by the product-profile check, but it is not yet a complete first-boot account-provisioning system or a claim of production-ready access control.
Credential details belong in Getting Started and the Security Policy, rather than being duplicated throughout the architecture documentation.
Build-to-image flow
The normal image build follows these stages:
-
Configuration resolution
.config, command-line Make variables, andmk/config.mkselect the architecture, product profile, output directory, package-source policy, and container behavior. -
Cross-toolchain provisioning
mk/prefix.mkprepares the compilers, linkers, runtime libraries, and target sysroot forx86_64-unknown-redox. -
Recipe resolution The selected filesystem configuration is passed to the repository build tool. Cookbook resolves the explicitly selected packages and their recipe dependencies.
-
Package construction or retrieval Recipes fetch pinned source revisions, apply local patches where declared, and compile or retrieve target package artifacts.
-
Host filesystem tools The build compiles the host-side installer and RedoxFS tools used to create and populate the target image.
-
Image assembly
mk/disk.mkcreates a temporary image, invokes the installer with the selected configuration, and moves the completed temporary file to its final artifact path only after installation succeeds. -
Artifact output The principal outputs are:
build/x86_64/<profile>/harddrive.img build/x86_64/<profile>/redox-live.iso
The installed disk and live image share the same product configuration but use different bootloader paths. The live-image target invokes the installer in live mode with the live bootloader, while the ordinary disk image is assembled as the persistent development or release disk.
The .iso suffix in redox-live.iso is an inherited build-interface name. It should not be renamed independently of the build, verification, and release contracts that consume it.
Boot-to-shell flow
For the primary x86_64 path, the runtime sequence is:
x86_64 UEFI firmware
→ FlashOS-branded bootloader
→ pinned Redox kernel with local branding patch
→ schemes, drivers, and init services
→ framebuffer console and input service
→ getty and login
→ /usr/bin/fsh
→ Flash built-ins or external userspace processes
The current QEMU configuration uses the q35 machine model and normally exposes the main disk through an emulated NVMe interface. The live-image qualification path exposes the live artifact as USB mass storage.
After the kernel starts, installed initialization scripts launch the required services and console login process. Authentication reads the configured user data and starts the shell path associated with the selected account.
This sequence is verified automatically for the defined QEMU configurations. It does not establish equivalent behavior on arbitrary physical hardware.
Flash integration
Flash source is maintained as a nested Cargo workspace under components/flash/. The workspace separates syntax processing, runtime evaluation, platform contracts, platform adaptation, and the fsh command-line binary.
The system-image package is defined by:
recipes/terminal/flash/recipe.toml
That recipe:
- snapshots tracked and non-ignored files from
components/flash/in the current checkout; - selects
crates/flash-cliinside that snapshot; - builds the binary named
fsh; - installs the resulting package into the target image.
In a clean CI or release checkout, the package input is therefore the Flash
tree belonging to that exact outer FlashOS revision. A local build also includes
tracked modifications and non-ignored untracked files under components/flash/
so component changes can be tested before commit. Ignored outputs such as Cargo
target/ directories are never copied into the recipe source. Updating Flash
does not require a self-referential follow-up recipe SHA.
Flash also distinguishes host and target integrations at compile time. macOS and Linux development builds use host-oriented configuration, history, and line-editing integrations, while the Redox target selects its target terminal editor path. A feature demonstrated in a host build must therefore not be documented as available inside FlashOS until the target path and image have been checked.
Detailed language behavior and internal crate design belong in the Flash Documentation and Flash Architecture.
Verification boundaries
Architecture, build success, runtime qualification, and hardware support are separate claims.
Product-profile contract
ci/check_profile.fsh statically verifies repository-level product invariants, including:
- the exact declared package set;
- separation of runtime packages from bootloader, debug, development, editor, and unqualified compatibility payloads;
- inclusion of the shared base profile;
- exclusion of selected graphical-stack identifiers;
- Flash login-shell paths;
- development and release profile alignment;
- release credential restrictions;
- required framebuffer, terminal, and audio scheme access;
- absence of Orbital and
/uiprofile paths; - version alignment;
- the exact in-tree Flash workspace source and immutable revisions for shipped external Git recipes;
- post-package installation of the final FlashOS identity files;
- presence of required local branding patches without inherited Redox product identity additions.
With --artifacts, the same check also verifies the selected staged-package metadata, preserved bootloader/kernel/development outputs, and the absence of excluded files from runtime stages. It does not boot an image.
Runtime contract
ci/qemu_smoke.py boots an already-built image and checks the observable x86_64 QEMU path. Its assertions cover firmware and bootloader progress, kernel startup, selected driver initialization, the exact versioned FlashOS login identity, login, the Flash prompt, target-side interactive editing, directory changes, script execution, redirection, external and structured pipelines, and foreground/background completion. The signal and stopped-job transition group remains outside that bounded qualification. The login assertion also rejects inherited Redox product-branding strings while retaining technical identifiers such as RedoxFS.
The smoke test consumes image bytes in snapshot mode and does not use a successful boot as permission to modify the promoted artifact.
Artifact and release evidence
Ready-candidate workflows build and checksum the canonical hard-drive image,
then pass it to a separate NVMe QEMU consumer. Release workflows additionally
build and boot the live image, generate the image inventory, and package and
attest the qualified release candidate. Protected main receives its visible
verification status by verifying exact tree identity with that pre-merge
candidate rather than by rerunning source tests.
These mechanisms provide traceability and evidence for specific artifacts. They should not be described as a blanket guarantee that every local build on every host is bit-for-bit identical.
The overall evidence model is documented in Verification and Testing, while exact script and workflow contracts belong in CI/CD Contracts.
What this architecture does not imply
Other repository architectures are supported FlashOS targets
They are not. Generic inherited code paths for other architectures remain in the build system, but the current FlashOS profiles, CI qualification, public scope, and release path are x86_64-specific.
Every upstream Redox feature is available
It is not. An upstream driver, package, architecture, or documented behavior becomes a FlashOS capability only when it is selected by the active profile and supported by appropriate FlashOS evidence.
FlashOS has an independent kernel and userspace stack
It does not. The project currently owns its product profile, identity, Flash, documentation, verification contracts, and selected patches while relying extensively on pinned upstream kernel, ABI, library, service, utility, packaging, and image-building components.
Branding patches replace technical dependencies
They do not. Branding patches change selected user-visible strings and identifiers. They do not by themselves alter the ownership or underlying architecture of the patched component.
TUI-only means no display, input, or audio support
It does not. The active profile excludes graphical desktop and windowing stacks while retaining the framebuffer console, keyboard input, terminal, networking, and audio paths required by the current product contract.
Flash is POSIX shell compatible
It is not intended to be a drop-in implementation of Bash or /bin/sh. Scripts and commands must follow the syntax and execution model documented for Flash.
A successful QEMU boot qualifies physical hardware
It does not. Physical-machine support requires device-specific evidence maintained in Hardware Compatibility.
Sources of truth
Use the following files when evaluating or changing an architectural contract:
| Concern | Primary source |
|---|---|
| Public product scope | README.md |
| Documentation responsibilities | docs/README.md |
| Shared image foundation | config/flashos-base.toml |
| Development image profile | config/x86_64/flashos.toml |
| Release image profile | config/x86_64/flashos-release.toml |
| Build-variable resolution | mk/config.mk |
| Cross-toolchain and sysroot | mk/prefix.mk |
| Package construction | mk/repo.mk and package recipes under recipes/ |
| Image assembly | mk/disk.mk |
| QEMU device model | mk/qemu.mk |
| Flash source architecture | components/flash/ |
| Flash image package | recipes/terminal/flash/recipe.toml |
| Product-profile invariants | ci/check_profile.fsh |
| Runtime qualification | ci/qemu_smoke.py |
| Release version | versions.env |
| Hardware evidence | Hardware Compatibility |
| Future direction | Roadmap |
| Upstream reference material | Upstream References |
When these sources disagree, configuration, recipes, executable checks, and current code take precedence over descriptive text. The documentation should then be corrected without treating an outdated statement as an implemented system contract.