Catcrafts builds of the postmarketos image for the fairphone 6
  • Shell 84.7%
  • Python 15.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jorijn van der Graaf e57149f496 fp6-vendor-blobs 1-r3: extract from the active slot, and stop pinning a hash on a signed image
Two field units got no fingerprint sensor from fingerprintd 0.2.3's
manifest: its focal64 line pinned the sha256 of one Android build's
trustlet (16.82.0, the dev phone's), and Fairphone re-signs that trustlet
every release, so the pin matches exactly one of the six builds seen. A
user on 16.100.0 had to edit the manifest by hand; another ended up with
a file QTEE refuses.

The extractor now tries the active slot's partitions first
(androidboot.slot_suffix from the kernel command line): for a signed
image only the running TZ's own slot is guaranteed to load. An mbn line
may give '-' instead of a hash, which means structural verification
only: ELF64 header, every segment present at the size its program header
declares, page-aligned offsets, a sane total. The loader in TZ verifies
the signature and the per-segment hashes itself and refuses a damaged or
foreign image (one flipped byte -> ERROR_ELF_SIGNATURE_ERROR, measured),
so the whole-image hash added fragility and no protection. A real sha256
is still honoured, and the sha256 of what was installed is logged either
way.

--refresh re-derives mbn dests even when a file exists, replacing it
only with an image that verifies; consumers call it from
post-install/post-upgrade so a fresh 'apk add' needs no reboot and a
hand-placed or wrongly pinned trustlet is replaced on the next upgrade.

Verified on the dev phone (busybox): malformed inputs are refused with a
reason (missing, truncated or oversize segment; non-ELF, ELF32 or short
mdt; a garbage offset), both slots reassemble to the known-good hash, a
foreign file survives a plain run and is replaced by --refresh, a failed
refresh keeps the old file, pins still work, and the real post-upgrade
path re-derived the installed trustlet with the daemon restarting on it.
Record: fp6 repo journal/blobs/ and journal/fingerprint/, 2026-09-11.
2026-09-11 13:10:00 +02:00
.forgejo/workflows Install fingerprintd from the registry, so the image unlocks with a finger 2026-09-05 20:31:37 +02:00
aports fp6-vendor-blobs 1-r3: extract from the active slot, and stop pinning a hash on a signed image 2026-09-11 13:10:00 +02:00
.gitignore gitignore dist/; fix empty then-branch (sh syntax) in the NV verdict 2026-08-09 02:44:39 +02:00
apk-resign.py imsd: sign from a readable copy of the abuild key 2026-09-02 17:21:30 +02:00
build.sh imsd 0.3.3-r0: landline callers ring 2026-09-08 20:24:07 +02:00
check-aports.sh fp6-vendor-blobs: the checksum the extractor change forgot, and a check that finds the next one in a second 2026-09-05 22:26:33 +02:00
install.sh debian fix 2026-08-29 00:40:38 +02:00
README.md Update README.md 2026-09-06 14:00:13 +00:00

fp6-img

Flashable postmarketOS images for the Fairphone 6/6+, built nightly from the Catcrafts milos-linux combined-stable kernel branch, with imsd (userspace VoLTE) preinstalled.

Maintained by Jorijn van der Graaf (TheMightyCat) at Catcrafts.

What works

Everything on the combined-stable branch: display, touch, wifi, cellular data, NFC (reader), speaker audio, microphone, IMU, magnetometer, barometer, ambient light/proximity, fingerprint unlock through fingerprintd, plus VoLTE calls (both directions) through imsd.

Flashing

Download fp6-img.tar.xz from the latest release and unlock the bootloader (Fairphone's official process).

Install: with the phone in fastboot mode,

tar xf fp6-img.tar.xz
cd fp6-img
./install.sh

install.sh erases dtbo, flashes the rootfs, RAM-boots the kernel, writes the boot partition from inside Linux where the bootloader's NV-wipe cannot see it, then reads the modem NV back and reports the result. The bootloader never writes boot.

Default login: user / 147147 (same as official postmarketOS images). Never re-lock the bootloader with a custom image installed.

VoLTE configuration

imsd is installed but needs your carrier's P-CSCF address:

# /etc/imsd.env
PCSCF=<your carrier's P-CSCF IPv6 address>

Find it via android adb using adb shell dumpsys telephony.registry, then systemctl restart imsd (the service is enabled at boot and waits for this file to exist). See the imsd README for the full variable reference and carrier assumptions.