Skip to content

Repository files navigation

flipperos-installer

A small installer for Rockchip RK3576 boards (the Flipper One and other RK3576 boards used for testing), designed to run from a Linux initramfs for on-device installs.

It can:

  • Discover the running board from the device tree (/proc/device-tree).
  • Enumerate local storage the RK3576 boot ROM can boot from (UFS, eMMC, SD) via sysfs.
  • Query the image server for available U-Boot images and exported profile snapshots for the board.
  • Search removable storage (SD / USB) for offline U-Boot images and profile snapshots.
  • Present a TUI (Cursive + Crossterm) for serial-console operation.
  • Present a GUI (Slint + LinuxKMS) on the Flipper One 256×144 DRM screen, driven by the on-device buttons (a Linux input event device).
  • Run the installation: blkdiscard, write a fresh GPT, mkfs.btrfs with a subvolume skeleton, btrfs receive the selected profile snapshots, and install a kernel for each.

Architecture

Both frontends are thin views over a single shared installer state:

                 ┌──────────────────────────────┐
   serial  ─────▶│  TUI (cursive/crossterm)     │─┐
   console       └──────────────────────────────┘ │  actions
                                                   ▼
                 ┌──────────────────────────────┐  Controller ── AppState
   on-device ───▶│  GUI (slint/linuxkms)        │─┐  (single source of truth)
   buttons       └──────────────────────────────┘ │  snapshots ▲
                                                   └────────────┘

Building

Built and tested with rustc 1.95.0 (via rustup). The GUI depends on Slint 1.17, which sets a minimum of rustc 1.92; the TUI-only build has a lower floor (its highest-MSRV dependency is uuid, at rustc 1.85).

This repository uses a git submodule for the on-device font (flipctl-fonts, tracking the dev branch). Clone recursively, or initialise it after cloning:

git clone --recurse-submodules <repo-url>
# or, in an existing checkout:
git submodule update --init --recursive
# Default: both frontends, host build (for development).
cargo build

# Release build for the device (RK3576 is ARMv8):
rustup target add aarch64-unknown-linux-gnu
cargo build --release --target aarch64-unknown-linux-gnu

# Slim, TUI-only variant (no GUI shared-library dependencies):
cargo build --release --no-default-features --features tui \
    --target aarch64-unknown-linux-gnu

The binary links dynamically against the system C library and, for the GUI, against libinput, libudev, libxkbcommon, libfontconfig and libfreetype (the last two pulled in by Slint for font discovery/rendering), all located via pkg-config. These shared libraries must therefore be present in the initramfs alongside the binary (the TUI-only build needs none of them). The drm crate talks to the kernel directly via ioctls (pregenerated bindings), so no libdrm is needed. Install the build tools and dev packages (Debian/Ubuntu):

sudo apt install pkg-config libinput-dev libudev-dev libxkbcommon-dev \
    libfontconfig-dev libfreetype-dev

The GUI's text is rendered with the compiled-in HaxrCorp 4090 (FlipCTL) pixel font (vendored as the third_party/flipctl-fonts submodule and embedded by the Slint compiler), so no system fonts are required on the device.

Cargo feature flags:

Feature Frontend
tui Cursive/Crossterm (serial)
gui Slint/LinuxKMS (on-device screen)

Running

# Both frontends concurrently (default), safe dry-run:
sudo ./flipperos-installer

# Serial console only:
sudo ./flipperos-installer --tui

# On-device screen only, real install, custom server:
sudo ./flipperos-installer --gui --no-dry-run \
    --server https://images.flipperos.example \
    --kms-device /dev/dri/by-path/platform-2acf0000.spi-cs-0-card

By default the installer runs in dry-run mode: every destructive command is logged but not executed. Pass --no-dry-run to actually flash.

Image sources

The installer reads the image server's two-level catalog (default base https://dl-linux-images.flipp.dev, override with --server):

  • U-Boot: /u-boot/manifest.json lists build directories; each build's manifest.json contains <board>/u-boot-rockchip.bin. The installer flashes <board>/u-boot-rockchip.bin for the detected board (flipper-one, else generic).
  • Snapshots (rootfs): /rootfs/manifest.json lists build directories; each build's manifest.json contains per-profile packs <Profile>_<build>_stock_pack.zst (full) and <Profile>_<build>_stock_inc_pack.zst (incremental delta vs. Minimal).

Both lists are presented newest first. The operator picks one U-Boot build and one snapshot build. Minimal is always deployed (from its full pack); any extra profiles the operator selects are streamed from their incremental packs on top of Minimal. Packs are zstd-compressed btrfs send streams, decompressed in-process and piped into btrfs receive.

A removable-media mirror of the same u-boot/ and rootfs/ tree is picked up automatically and merged into the lists.

Btrfs layout

The shared, top-level Btrfs subvolume skeleton (boot, @home, @var-log, @var-cache, @snapshots, with boot kept uncompressed and the journal dir NODATACOW) is described by a small TOML file that mirrors the build recipe. See config/flipperos-btrfs.toml.

At install time the installer prefers a btrfs-layout.toml shipped with the images and falls back to the copy compiled into the binary. Per-profile roots (@Minimal, @Desktop, …) are not listed there — they are received from the selected snapshot packs.

Status

This is an early scaffold: the architecture, discovery, both frontends and the dry-run install pipeline are in place. GPT partitioning and the U-Boot write are done in-process (gpt crate); the remaining destructive steps shell out to blkdiscard, mkfs.btrfs, btrfs and chattr. Kernel installation is driven by an embedded POSIX shell script (scripts/flipperos-install-kernel.sh) that chroots into each deployed profile and runs the profile's own kernel-install for every installed kernel, writing into the shared /boot subvolume. These tools (mount/umount, chroot, sh, and the profile's kernel-install) must be present in the initramfs / profile.

Licensing

The installer's own source in this repository is MIT-licensed (see LICENSES/MIT.txt; the repository follows the REUSE specification, so reuse lint is green).

However, the shipped binary links the Slint GUI toolkit, which we use under the GNU GPL v3.0 option of its tri-license (wehold no separate Slint agreement, and want the binary to be buildable purely from public sources). Linking GPL code makes the combined binary as a whole GPL-3.0-only. MIT is GPL-compatible, so our own sources are unaffected and may still be reused under MIT on their own.

Full license texts for every crate linked into the binary are collected in THIRD-PARTY-LICENSES.md. Regenerate it from the current Cargo.lock whenever dependencies change:

cargo install cargo-about --features cli   # once
sh scripts/gen-third-party-licenses.sh

The bundled fonts live in the third_party/flipctl-fonts submodule and carry their own licenses (HaxrCorp 4090 — CC BY-SA 3.0; Born2bSportyV2 — The Unlicense; Busy9px — MIT); see the LICENSE file in each font's folder.

About

Small Rust program designed to run from a Linux initramfs and install a complete Flipper OS

Resources

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages