You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Flipper OS concept says you're not 100% sure how to architect profiles yet, so here's a concrete comparison and a proposal. I've built profile-ish setups on RK3399/RPi boards and most of the pain is in the update story and the bootloader handoff, so I'll focus there.
The concept page pins the constraints: Debian base, apt must keep working inside a profile, instant clone/reset, boot-menu selection before Linux starts (so U-Boot is involved), SD-card friendliness, and a mental model a non-expert can hold.
Options
apt works inside
clone/reset
disk overhead
base update
mental model
pre-Linux boot pick
(a) btrfs subvol + overlay /etc..rootfs
yes
instant (snapshot)
CoW deltas only
atomic (new RO subvol)
"bootable folders"
easy (rootflags/initramfs)
(b) ostree/composefs
no (image-based; apt-ostree still incubating in StarlingX)
checkout = cheap
low (hardlinks)
excellent, it's the whole point
hardest
ok
(c) A/B raw partitions
yes
no — fixed slots, full copies
worst
good
fine
easy
(d) systemd-sysext/confext
no (extensions are read-only /usr+/etc overlays)
n/a
low
good
leaky
poor
(e) nspawn containers
yes
cheap if on btrfs anyway
low
host rots again
leaky ("am I in the container?")
indirect — host boots first
(b) is the right answer for an appliance, wrong for this device: "users configure the system in the usual way using the package manager" is the stated requirement, and ostree breaks exactly that. (c) doesn't scale past two profiles. (d) is for vendor add-ons, not user-writable state. (e) deserves a real look — apt works, kernel is shared — but this device's whole point is raw hardware ownership (monitor mode, netdev juggling, kernel modules, DT overlays from a profile), and containers fight you on all of it. Worse, the host OS becomes a new thing that rots, which is the original problem recursed.
Proposal: (a), structured as your docs already describe it
One btrfs partition, plus a small FAT boot partition for U-Boot/extlinux/kernels:
@base/<version> read-only Debian rootfs, shipped via update (btrfs send/receive stream)
@profiles/<id>/upper overlayfs upperdir (+workdir) — ALL profile state
@data user files, mounted into every profile
A profile is literally "an overlay on top of the base system" — the wording from the concept page, made into a mount: lowerdir=@base/current,upperdir=@profiles/<id>/upper. apt/dpkg work unmodified (Docker has run apt-in-overlayfs at planetary scale for a decade; the old dpkg rename quirks are handled). Then:
Clone = btrfs subvolume snapshot of the upper — instant, CoW, costs ~nothing.
Rollback = auto-snapshot the upper before apt runs (apt/dpkg hook), expose "undo last change" in FlipCTL.
Atomic base update = receive @base/<v+1> as a complete subvolume, flip a symlink, reboot. Old base stays until GC → instant rollback, and an interrupted update changes nothing. This answers the "reliable atomic updates" question without ostree.
SD wear: CoW naturally spreads writes; mount noatime,commit=120. Profiles on removable SD = same subvolume layout on a second btrfs filesystem.
The honest cost: when @base jumps a Debian release, a profile's upper can hold stale conffiles/packages that conflict with the new lower. Every overlay system has this; mitigation is keeping base minimal (kernel + core userspace) so officials profiles carry their packages in the upper, and a flipper-profile check that diffs upper contents against the new base before flipping.
Boot menu / U-Boot
#68 already has FlipCTL rewriting the extlinux.conf default entry — fine from a running system, but the MCU can't write eMMC, so the pre-Linux picker has to hand the selection across the interconnect. U-Boot already talks I2C, and the interconnect has I2C + UART + GPIO between RP2350 and the SoC. Cleanest: boot.scr does i2c read of a "selected profile" register the MCU exposes (fallback: saved env), then appends flipper.profile=<id> flipper.base=<ver> to bootargs. A ~30-line initramfs hook mounts btrfs, assembles the overlay, switch_root. Keeping kernel+initramfs on the FAT partition avoids depending on U-Boot's btrfs reader (it exists, but FAT is boring and proven). One LABEL per profile in extlinux.conf also works and matches the current flow, but sysboot can't be steered to a label non-interactively, so env + boot.scr composes better with the MCU.
Step 2: rootfs → btrfs, whole-rootfs-as-subvolume, profiles as full-fork snapshots. No overlay, no initramfs logic beyond rootflags=subvol=. Boot/clone/reset all work; ship the FlipCTL UI against this.
Step 3: split RO @base + overlay uppers; add the initramfs hook and send/receive base updates. Existing full-fork profiles migrate by diffing against the base they forked from.
Step 4: per-profile metadata (name, dates, origin — a JSON file inside the subvolume), apt snapshot hook, update agent.
Step 2 alone already kills the SD-card-shuffling workflow, which is the headline user win.
Open questions I'd want input on: per-profile /var and machine-id (share logs or isolate?), and whether a profile may carry its own DT overlays/cmdline fragment (I'd say yes — metadata file consumed by boot.scr).
The Flipper OS concept says you're not 100% sure how to architect profiles yet, so here's a concrete comparison and a proposal. I've built profile-ish setups on RK3399/RPi boards and most of the pain is in the update story and the bootloader handoff, so I'll focus there.
The concept page pins the constraints: Debian base, apt must keep working inside a profile, instant clone/reset, boot-menu selection before Linux starts (so U-Boot is involved), SD-card friendliness, and a mental model a non-expert can hold.
Options
rootflags/initramfs)/usr+/etcoverlays)(b) is the right answer for an appliance, wrong for this device: "users configure the system in the usual way using the package manager" is the stated requirement, and ostree breaks exactly that. (c) doesn't scale past two profiles. (d) is for vendor add-ons, not user-writable state. (e) deserves a real look — apt works, kernel is shared — but this device's whole point is raw hardware ownership (monitor mode, netdev juggling, kernel modules, DT overlays from a profile), and containers fight you on all of it. Worse, the host OS becomes a new thing that rots, which is the original problem recursed.
Proposal: (a), structured as your docs already describe it
One btrfs partition, plus a small FAT boot partition for U-Boot/extlinux/kernels:
A profile is literally "an overlay on top of the base system" — the wording from the concept page, made into a mount:
lowerdir=@base/current,upperdir=@profiles/<id>/upper. apt/dpkg work unmodified (Docker has run apt-in-overlayfs at planetary scale for a decade; the old dpkg rename quirks are handled). Then:btrfs subvolume snapshotof the upper — instant, CoW, costs ~nothing.aptruns (apt/dpkg hook), expose "undo last change" in FlipCTL.@base/<v+1>as a complete subvolume, flip a symlink, reboot. Old base stays until GC → instant rollback, and an interrupted update changes nothing. This answers the "reliable atomic updates" question without ostree.noatime,commit=120. Profiles on removable SD = same subvolume layout on a second btrfs filesystem.The honest cost: when
@basejumps a Debian release, a profile's upper can hold stale conffiles/packages that conflict with the new lower. Every overlay system has this; mitigation is keeping base minimal (kernel + core userspace) so officials profiles carry their packages in the upper, and aflipper-profile checkthat diffs upper contents against the new base before flipping.Boot menu / U-Boot
#68 already has FlipCTL rewriting the
extlinux.confdefault entry — fine from a running system, but the MCU can't write eMMC, so the pre-Linux picker has to hand the selection across the interconnect. U-Boot already talks I2C, and the interconnect has I2C + UART + GPIO between RP2350 and the SoC. Cleanest:boot.scrdoesi2c readof a "selected profile" register the MCU exposes (fallback: saved env), then appendsflipper.profile=<id> flipper.base=<ver>to bootargs. A ~30-line initramfs hook mounts btrfs, assembles the overlay,switch_root. Keeping kernel+initramfs on the FAT partition avoids depending on U-Boot's btrfs reader (it exists, but FAT is boring and proven). OneLABELper profile in extlinux.conf also works and matches the current flow, but sysboot can't be steered to a label non-interactively, so env + boot.scr composes better with the MCU.MVP path
rootflags=subvol=. Boot/clone/reset all work; ship the FlipCTL UI against this.@base+ overlay uppers; add the initramfs hook andsend/receivebase updates. Existing full-fork profiles migrate by diffing against the base they forked from.Step 2 alone already kills the SD-card-shuffling workflow, which is the headline user win.
Open questions I'd want input on: per-profile
/varandmachine-id(share logs or isolate?), and whether a profile may carry its own DT overlays/cmdline fragment (I'd say yes — metadata file consumed by boot.scr).