From dabfb4f4e382caeb8f9645b65a58ca30a261ce5c Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Fri, 25 Sep 2026 00:04:52 +0200 Subject: [PATCH 1/7] fp6-device-tweaks 5-r1: restart drop-in comment matches the no-SSC rule The drop-in's header still presented the boot-time libssc crash as live; the udev rule from the previous commit removes the probe that caused it. Comment only, no behaviour change; bumped so the rebuilt package carries it. --- aports/device/fp6-device-tweaks/APKBUILD | 4 ++-- .../device/fp6-device-tweaks/iio-sensor-proxy-restart.conf | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/aports/device/fp6-device-tweaks/APKBUILD b/aports/device/fp6-device-tweaks/APKBUILD index fa91f23..4e288b0 100644 --- a/aports/device/fp6-device-tweaks/APKBUILD +++ b/aports/device/fp6-device-tweaks/APKBUILD @@ -20,7 +20,7 @@ maintainer="Jorijn van der Graaf " pkgname=fp6-device-tweaks pkgver=5 -pkgrel=0 +pkgrel=1 pkgdesc="Fairphone 6 device-critical system configuration" url="https://forgejo.catcrafts.net/Catcrafts/fp6-img" arch="noarch" @@ -58,7 +58,7 @@ package() { sha512sums=" 5e60fef47cb09cec7cab73464183dfd9e9cb32cebd1d20a67922c10c5a747eca8d106b66737d06af5c5c162a6baf37ab62a82709cc20911044face100d482919 inv-icm42600.conf cc13f6abc4538fef976c59893992dd2c193cd0eac5da37a9fb01ba421b3ba8ff303aa438ec2fe4d10f50165f90be211d4b2c39dc6ef58d0d320fba8182ccf287 81-fp6-accel-poll.rules -1800ad5c11b4e38c10b0c72b2392a6dc978a4e37bcd964182adb90d7d9aa7afc74acf102e2051dbf864021c05821f683af8943e2729e1eaa195856a0bd635e09 iio-sensor-proxy-restart.conf +f74c6c5d0ba3015cf123808452e9677c1d087e9540ea7037c30316e48a5c5bbdafe712ff0b07f17969337b1576a34cdfef4319c464ffe38c092a67d313129b57 iio-sensor-proxy-restart.conf 8fec832be59ca616d3e6a4c0a5ef8067d25f767c79155d8b0ef5761b8d21532932235a3236807305937029efe6255a16696d05523e3e654e2dc2212a281fe12c modem-gnss-nmea-optional.conf 1c5fd4a5a2a2c19165dca1381c8c6550fb61c6311561be450c9c6f88046d7649e4c7c6f4a86b163a2ecc1ef5ec93cc1dac1e2aded933a6b3d6d68292a1b609d0 91-fp6-no-ssc-sensors.rules " diff --git a/aports/device/fp6-device-tweaks/iio-sensor-proxy-restart.conf b/aports/device/fp6-device-tweaks/iio-sensor-proxy-restart.conf index da589a7..8b70d55 100644 --- a/aports/device/fp6-device-tweaks/iio-sensor-proxy-restart.conf +++ b/aports/device/fp6-device-tweaks/iio-sensor-proxy-restart.conf @@ -1,5 +1,6 @@ -# Revive after the known boot-time libssc crash (unconfigured SSC); -# recreated 2026-07-28 - the 2026-07-20 drop-in had gone missing. +# Generic on-failure safety net. The boot-time libssc crash this was written +# for (2026-07-20, recreated 2026-07-28) is prevented by +# 91-fp6-no-ssc-sensors.rules since fp6-device-tweaks 5. [Unit] StartLimitIntervalSec=0 [Service] From 71ee495d6fa87dbd58738c66f9a3fbe2e4f9b181 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Mon, 12 Oct 2026 00:40:13 +0200 Subject: [PATCH 2/7] modemmanager 1.25.95_git20261005-r101: follow Alpine's snapshot Alpine's community/modemmanager moved to upstream commit 7f0bf17a (2026-10-05, 63 commits past our d776ea38) and now carries the XMM7360 big-endian patch itself. Its 1.25.95_git20261005-r0 sorts above our 1.25.95_git20260709-r101, so the next 'apk upgrade' on a phone would have replaced this fork with Alpine's build and dropped the two GNSS patches (MR !1463, still not merged). Move the pin to Alpine's commit; the two GNSS patches re-exported on it (the same lines, only the hunk offsets moved, the result equal to the merge request's current head); keep the XMM7360 patch, which Alpine's aport has byte-for-byte. The makedepends no longer pin libqmi-dev to >=1.39.1: the GNSS patch raises meson's own qmi-glib requirement to 1.39.1 and every libqmi snapshot in reach reports that, while apk's view of Alpine's 1.38.0_git* version would fail the pin. --- ...ck-AFW-gated-GNSS-engines-at-LOC-star.patch | 18 +++++++++--------- ...ve-location-from-Position-Report-indi.patch | 15 +++++++-------- aports/temp/modemmanager/APKBUILD | 13 ++++++++----- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/aports/temp/modemmanager/0002-shared-qmi-unlock-AFW-gated-GNSS-engines-at-LOC-star.patch b/aports/temp/modemmanager/0002-shared-qmi-unlock-AFW-gated-GNSS-engines-at-LOC-star.patch index b1079f8..17d9e28 100644 --- a/aports/temp/modemmanager/0002-shared-qmi-unlock-AFW-gated-GNSS-engines-at-LOC-star.patch +++ b/aports/temp/modemmanager/0002-shared-qmi-unlock-AFW-gated-GNSS-engines-at-LOC-star.patch @@ -1,7 +1,7 @@ -From 2924dab906b3dc9e3b48e766637618ce53615c23 Mon Sep 17 00:00:00 2001 +From d9e93ad09b75ec2813a01bbb07794a5c85a3a56d Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Thu, 2 Jul 2026 15:30:48 +0200 -Subject: [PATCH 2/3] shared-qmi: unlock AFW-gated GNSS engines at LOC start +Subject: [PATCH] shared-qmi: unlock AFW-gated GNSS engines at LOC start Newer Snapdragon GNSS engines (e.g. gnss8 in the SM7635/Fairphone 6) only allow positioning for clients registered as application framework @@ -44,10 +44,10 @@ Signed-off-by: Jorijn van der Graaf 2 files changed, 86 insertions(+), 55 deletions(-) diff --git a/meson.build b/meson.build -index 3cf29e80..e5e3d0be 100644 +index 9b8ab2d1..1bb10b94 100644 --- a/meson.build +++ b/meson.build -@@ -277,7 +277,7 @@ config_h.set('WITH_MBIM', enable_mbim) +@@ -297,7 +297,7 @@ config_h.set('WITH_MBIM', enable_mbim) # QMI support (enabled by default) enable_qmi = get_option('qmi') if enable_qmi @@ -57,10 +57,10 @@ index 3cf29e80..e5e3d0be 100644 if not qmi_glib_dep.found() and get_option('subproject-fallback') diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c -index d93698a6..09aa987a 100644 +index f578d876..25990ceb 100644 --- a/src/mm-shared-qmi.c +++ b/src/mm-shared-qmi.c -@@ -5646,33 +5646,67 @@ pds_gps_service_state_start_ready (QmiClientPds *client, +@@ -5652,33 +5652,67 @@ pds_gps_service_state_start_ready (QmiClientPds *client, qmi_message_pds_set_auto_tracking_state_input_unref (input); } @@ -142,7 +142,7 @@ index d93698a6..09aa987a 100644 self = g_task_get_source_object (task); priv = get_private (self); -@@ -5691,16 +5725,16 @@ loc_register_events_ready (QmiClientLoc *client, +@@ -5697,16 +5731,16 @@ loc_register_events_ready (QmiClientLoc *client, } static void @@ -167,7 +167,7 @@ index d93698a6..09aa987a 100644 if (!output) { g_prefix_error (&error, "QMI operation failed: "); g_task_return_error (task, error); -@@ -5708,32 +5742,40 @@ loc_start_ready (QmiClientLoc *client, +@@ -5714,32 +5748,40 @@ loc_start_ready (QmiClientLoc *client, return; } @@ -226,7 +226,7 @@ index d93698a6..09aa987a 100644 static void start_gps_engine (MMSharedQmi *self, GAsyncReadyCallback callback, -@@ -5771,20 +5813,9 @@ start_gps_engine (MMSharedQmi *self, +@@ -5777,20 +5819,9 @@ start_gps_engine (MMSharedQmi *self, MM_PORT_QMI_FLAG_DEFAULT, NULL); if (client) { diff --git a/aports/temp/modemmanager/0003-shared-qmi-derive-location-from-Position-Report-indi.patch b/aports/temp/modemmanager/0003-shared-qmi-derive-location-from-Position-Report-indi.patch index 380d3d7..eb5019d 100644 --- a/aports/temp/modemmanager/0003-shared-qmi-derive-location-from-Position-Report-indi.patch +++ b/aports/temp/modemmanager/0003-shared-qmi-derive-location-from-Position-Report-indi.patch @@ -1,8 +1,7 @@ -From 7566587e77d299ab0f67613ae03cab9973e351db Mon Sep 17 00:00:00 2001 +From 59f2f17246a844e07569e2ee6523c810364e1e52 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Thu, 2 Jul 2026 15:44:16 +0200 -Subject: [PATCH 3/3] shared-qmi: derive location from Position Report - indications +Subject: [PATCH] shared-qmi: derive location from Position Report indications Some GNSS engines (e.g. gnss8 in the SM7635/Fairphone 6) report fixes only via QMI_LOC Position Report indications and never emit NMEA (Set @@ -43,7 +42,7 @@ Signed-off-by: Jorijn van der Graaf 1 file changed, 147 insertions(+) diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c -index 09aa987a..cad75080 100644 +index 25990ceb..d2eefb26 100644 --- a/src/mm-shared-qmi.c +++ b/src/mm-shared-qmi.c @@ -88,6 +88,8 @@ typedef struct { @@ -64,7 +63,7 @@ index 09aa987a..cad75080 100644 if (priv->loc_assistance_inject_time_req_indication_id) g_signal_handler_disconnect (priv->loc_client, priv->loc_assistance_inject_time_req_indication_id); if (priv->loc_assistance_inject_position_req_indication_id) -@@ -5161,6 +5165,10 @@ loc_stop_ready (QmiClientLoc *client, +@@ -5167,6 +5171,10 @@ loc_stop_ready (QmiClientLoc *client, g_signal_handler_disconnect (priv->loc_client, priv->loc_location_nmea_indication_id); priv->loc_location_nmea_indication_id = 0; } @@ -75,7 +74,7 @@ index 09aa987a..cad75080 100644 g_clear_object (&priv->loc_client); } -@@ -5264,11 +5272,142 @@ loc_location_nmea_indication_cb (QmiClientLoc *client, +@@ -5270,11 +5278,142 @@ loc_location_nmea_indication_cb (QmiClientLoc *client, if (!nmea) return; @@ -218,7 +217,7 @@ index 09aa987a..cad75080 100644 /*****************************************************************************/ /* Location: internal helper: setup minimum required NMEA traces */ -@@ -5662,6 +5801,7 @@ gps_engine_loc_register_events (QmiClientLoc *client, +@@ -5668,6 +5807,7 @@ gps_engine_loc_register_events (QmiClientLoc *client, guint64 event_mask; event_mask = QMI_LOC_EVENT_REGISTRATION_FLAG_NMEA | @@ -226,7 +225,7 @@ index 09aa987a..cad75080 100644 QMI_LOC_EVENT_REGISTRATION_FLAG_INJECT_TIME_REQUEST | QMI_LOC_EVENT_REGISTRATION_FLAG_INJECT_POSITION_REQUEST; input = qmi_message_loc_register_events_input_new (); -@@ -5713,12 +5853,19 @@ loc_start_ready (QmiClientLoc *client, +@@ -5719,12 +5859,19 @@ loc_start_ready (QmiClientLoc *client, g_assert (!priv->loc_client); g_assert (!priv->loc_location_nmea_indication_id); diff --git a/aports/temp/modemmanager/APKBUILD b/aports/temp/modemmanager/APKBUILD index 569d1e6..d5ef067 100644 --- a/aports/temp/modemmanager/APKBUILD +++ b/aports/temp/modemmanager/APKBUILD @@ -1,12 +1,15 @@ # fp6-img fork of Alpine community/modemmanager: + the AFW-gated GNSS # engine unlock + Position Report location derivation (upstream MR !1463, -# still draft) - the other half of working GNSS on the FP6. +# still draft) - the other half of working GNSS on the FP6. Snapshot and +# the XMM7360 patch follow Alpine's aport (2026-10-05); the pkgver must stay +# ahead of Alpine's, or 'apk upgrade' replaces this package with theirs and +# the phone loses GNSS. # Contributor: Stuart Cardall maintainer="Achill Gilgenast " pkgname=modemmanager -pkgver=1.25.95_git20260709 +pkgver=1.25.95_git20261005 pkgrel=101 -_commit=d776ea38d29ca472a12323c1d45002ee19a66f57 +_commit=7f0bf17ab518cd78925cf7e53cc0d5c42f88b41a pkgdesc="ModemManager library" url="https://www.freedesktop.org/wiki/Software/ModemManager" arch="all" @@ -29,7 +32,7 @@ makedepends=" gtk-doc libgudev-dev libmbim-dev - libqmi-dev>=1.39.1 + libqmi-dev linux-headers meson polkit-dev @@ -118,7 +121,7 @@ libmm() { } sha512sums=" -fd659330b2ec4e8368807053ec01498241dec153f6f2491bb17c42e2b81c8d9a98ff5f8c153874a6d092e17c545c5ae19734bc23c85c459eb1c7b9b709e5ff58 ModemManager-d776ea38d29ca472a12323c1d45002ee19a66f57.tar.gz +fd659330b2ec4e8368807053ec01498241dec153f6f2491bb17c42e2b81c8d9a98ff5f8c153874a6d092e17c545c5ae19734bc23c85c459eb1c7b9b709e5ff58 ModemManager-7f0bf17ab518cd78925cf7e53cc0d5c42f88b41a.tar.gz 6fab86c27502b29be0c6610d835a3249a4a81993eb986cff2c3ea9393fadd3f693ba4bb0532ae0e50a83d359559511859dd05f7ea2f0cb52839f535a7e49f8a0 modemmanager.rules 6e234cebcdec6d1afbca164ee5c13c96f7132ef31231d5c043cc5750ebe99e362a384d0463874b3c1c30799b433e0d3286add03af13c97fa406b4b5d2b78880c modemmanager.initd f06e9b89acab5b61c5965658d62551b0f168066384674f7c4dd56feb6f811c82c640470e634e32d8c4ef62290588cf974aa5f213e5c67e797a06d33e61fa24ec 0001-intel-XMM7360-fix-big-endian-handling-of-ASN-integer.patch From 7157c54b100feb0b8444736816b1747b015d7421 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Mon, 12 Oct 2026 00:40:13 +0200 Subject: [PATCH 3/7] drop the libqmi fork: Alpine's snapshot is past the !470 merge Alpine's community/libqmi is at upstream 1c972b8a (2026-10-05), 23 commits past the 30f3e998 this fork pinned "just past the !470 merge", with the qmi-glib 1.39.1 the GNSS patches in modemmanager need. No patch was left; the fork's one remaining addition, the FP6-tuned build (-march/-mtune, whose gain was never measured), goes with it. build.sh loses its tarball, checksum and build steps. The registry still serves the fork (1.39.1_git20260808-r100 and -r101), and that version outranks Alpine's 1.38.0_git* line, so with the aport alone installed phones keep the fork and a fresh image takes it back at its first 'apk upgrade': the fork's packages are deleted from the registry with this push. Fresh images then install Alpine's libqmi and keep it. Installed phones keep the fork until 'apk upgrade -a' downgrades them to Alpine's or Alpine's version passes 1.39.1; the new modemmanager works on either (verified on the FP6 with both). pmbootstrap keeps a local package repository in its work dir and consults it before every other repository. Whether that dir survives from one CI run to the next is not established (run 60 rebuilt libqmi, modemmanager and libcamera at the versions run 58 had built, which says it did not), but nothing guarantees it either way, so build.sh deletes any libqmi/qmi-utils apks found there before building, re-indexes the repository from the files present and fails the run if any are left; the publish step skips libqmi-*/qmi-utils-* as the backstop. pmbootstrap's 'zap --pkgs-local-mismatch' cannot do this: with systemd selected it looks at packages/systemd-edge, not at the packages/edge the builds land in. --- .forgejo/workflows/build.yml | 8 ++- aports/device/catcrafts-fp6-repo/APKBUILD | 2 +- aports/temp/libqmi/APKBUILD | 77 ----------------------- build.sh | 39 +++++++----- 4 files changed, 31 insertions(+), 95 deletions(-) delete mode 100644 aports/temp/libqmi/APKBUILD diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 0eff8b4..2046b11 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -52,14 +52,17 @@ jobs: path: dist/* if-no-files-found: error - # Ship every locally built apk (kernel, modemmanager, libqmi, - # callaudioshim, audio files, ...) to the Forgejo Alpine registry, so + # Ship every locally built apk (kernel, modemmanager, callaudioshim, + # audio files, ...) to the Forgejo Alpine registry, so # installed systems get updates via 'apk upgrade' instead of losing # the FP6 patches to the next upstream version bump. Requires the # PACKAGE_TOKEN repo secret (catbot account, package:write scope); # skips quietly until it exists. 409 = same version already published. # imsd and fingerprintd are skipped: build.sh 3b took them FROM the # registry (re-signed for the chroot), so they are not ours to publish. + # libqmi is skipped too: its fork was retired and deleted from the + # registry (2026-10-12); should a leftover apk ever sit in the runner's + # package dir, it must not bring the fork back. - name: Publish packages to the apk registry env: PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }} @@ -74,6 +77,7 @@ jobs: [ -e "$f" ] || continue case "$(basename "$f")" in imsd-*|fingerprintd-*) echo "registry-sourced, not republished: $(basename "$f")"; continue ;; + libqmi-*|qmi-utils-*) echo "retired fork, not republished: $(basename "$f")"; continue ;; esac found=1 code=$(curl -s -o /dev/null -w '%{http_code}' \ diff --git a/aports/device/catcrafts-fp6-repo/APKBUILD b/aports/device/catcrafts-fp6-repo/APKBUILD index 54b915c..b28d9f5 100644 --- a/aports/device/catcrafts-fp6-repo/APKBUILD +++ b/aports/device/catcrafts-fp6-repo/APKBUILD @@ -1,7 +1,7 @@ # Enables the Catcrafts FP6 package repository on the installed system: # installs the Forgejo package-registry signing key and appends the repo URL # to /etc/apk/repositories. With this, 'apk upgrade' pulls the CI-published -# kernel/modemmanager/libqmi/imsd builds instead of losing the FP6 patches +# kernel/modemmanager/imsd builds instead of losing the FP6 patches # to the next upstream version bump. maintainer="Jorijn van der Graaf " pkgname=catcrafts-fp6-repo diff --git a/aports/temp/libqmi/APKBUILD b/aports/temp/libqmi/APKBUILD deleted file mode 100644 index bb04704..0000000 --- a/aports/temp/libqmi/APKBUILD +++ /dev/null @@ -1,77 +0,0 @@ -# fp6-img fork of Alpine community/libqmi: snapshot bumped to upstream main -# just past the !470 merge (LOC Register Events client-identification TLVs, -# half of working GNSS on the FP6) - which also provides the qmi-glib 1.39.1 -# our modemmanager patches require. Drop when Alpine's snapshot catches up. -# Contributor: Stuart Cardall -maintainer="Achill Gilgenast " -pkgname=libqmi -pkgver=1.39.1_git20260808 -_commit=30f3e998e6cbda364ac1bc73223de20561e6d555 -pkgrel=101 -pkgdesc="QMI modem protocol helper library" -url="https://www.freedesktop.org/wiki/Software/libqmi" -arch="all" -license="GPL-2.0-or-later AND LGPL-2.1-or-later" -makedepends=" - bash-completion-dev - glib-dev - gobject-introspection-dev - help2man - libgudev-dev - libmbim-dev - libqrtr-glib-dev - linux-headers - meson - python3 - " -# fp6-img: crossdirect breaks meson compiler introspection (cc1 spawn -# failure), same as modemmanager; build under plain qemu. -options="!pmb:crossdirect" -# fp6-img: this package only ever runs on the FP6 (4x Cortex-A520 + 4x -# Cortex-A720), so build for it. armv8.6-a is the highest level whose -# mandatory set the phone exposes (8.7 would assume WFxT, 9.x SVE2; neither -# is in its hwcaps); +fp16fml+aes+sha3+sm4 are the optional extensions it -# has, the same set `gcc -march=native` derives on the phone. One spelling -# for gcc and clang, and the same string the kernel aport uses. -export CFLAGS="$CFLAGS -march=armv8.6-a+fp16fml+aes+sha3+sm4 -mtune=cortex-a720" -subpackages=" - $pkgname-dev - $pkgname-doc - $pkgname-bash-completion - qmi-utils - " -#source="https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/archive/$pkgver/libqmi-$pkgver.tar.gz" -# fp6-img: local tarball, generated by build.sh from a git clone — fd.o's -# archive endpoint 504s for hours at a stretch (killed CI runs 27/30/31) -source="libqmi-$_commit.tar.gz - " -builddir="$srcdir/$pkgname-$_commit" - -build() { - abuild-meson \ - -Db_lto=true \ - . output - meson compile -C output -} - -check() { - local tests=$(meson test --list -C output) - case "$CARCH" in - s390x) tests=${tests//test-message} ;; - esac - meson test --print-errorlogs -C output $tests -} - -package() { - DESTDIR="$pkgdir" meson install --no-rebuild -C output -} - -utils() { - pkgdesc="$pkgdesc (CLI utilities)" - - amove usr/bin -} - -sha512sums=" -fc178689675b47faaa46c14b126dc054354044238ea00464b4cc4910c5f2c73faaa12d80a5219fbfad65ab575e38f7af3fd79ae7974ea80ed67bfffe027b85c3 libqmi-cff17a676e10d75081516dafa997fe9bc9043c38.tar.gz -" diff --git a/build.sh b/build.sh index ea021bf..6852a95 100755 --- a/build.sh +++ b/build.sh @@ -153,7 +153,6 @@ clone_retry "$WORK/pmaports" -q --depth=1 "$PMAPORTS_REPO" rm -rf "$WORK/pmaports/device/testing/linux-postmarketos-qcom-milos" \ "$WORK/pmaports/main/postmarketos-config-nftables" \ "$WORK/pmaports/temp/libcamera" \ - "$WORK/pmaports/temp/libqmi" \ "$WORK/pmaports/temp/modemmanager" mkdir -p "$WORK/pmaports/temp" cp -r aports/device/linux-postmarketos-qcom-milos "$WORK/pmaports/device/testing/" @@ -166,9 +165,9 @@ cp -r aports/device/fp6-charging-mode "$WORK/pmaports/device/" cp -r aports/device/catcrafts-fp6-repo "$WORK/pmaports/device/" cp -r aports/main/postmarketos-config-nftables "$WORK/pmaports/main/" # imsd has no aport here at all: section 3b installs the published apk. -# Alpine forks carrying the GNSS patches (libqmi !470 unreleased; MM !1463 -# draft) - deps of modemmanager/imsd, built from aports because r100 > repo. -cp -r aports/temp/libqmi "$WORK/pmaports/temp/" +# Alpine fork carrying the GNSS patches (MM !1463, draft), built from aports +# because r101 > repo. libqmi needs no fork any more: Alpine's snapshot +# (1.38.0_git20261005) is past the !470 merge. cp -r aports/temp/modemmanager "$WORK/pmaports/temp/" # pmOS libcamera fork + the FP6 OV13B10 sensor-helper/properties patches # (r2 > pmOS r1) @@ -191,7 +190,7 @@ sed -i "s/^_commit=.*/_commit=\"$COMMIT\"/" "$KAPORT/APKBUILD" KDATE=$(git -C "$WORK/milos-src" log -1 --format=%cd --date=format:%Y%m%d) sed -i "s/^pkgver=\([0-9.]*\)\$/pkgver=\1_git$KDATE/" "$KAPORT/APKBUILD" -# Same dance for the gitlab.freedesktop.org packages (libqmi, modemmanager, +# Same dance for the gitlab.freedesktop.org packages (modemmanager, # libcamera): their pinned tarballs came from fd.o's on-demand archive # endpoint, which 503/504s for hours at a stretch — runs #25, #27, #30 and # #31 all died there, outlasting any in-run retry. git clone is served from @@ -209,9 +208,6 @@ fdo_tarball() { # fdo_tarball } FDO=https://gitlab.freedesktop.org -QMI_COMMIT=$(apkbuild_var "$WORK/pmaports/temp/libqmi" _commit) -fdo_tarball "$FDO/mobile-broadband/libqmi.git" \ - "$WORK/pmaports/temp/libqmi" "libqmi-$QMI_COMMIT" "$QMI_COMMIT" MM_COMMIT=$(apkbuild_var "$WORK/pmaports/temp/modemmanager" _commit) fdo_tarball "$FDO/mobile-broadband/ModemManager.git" \ "$WORK/pmaports/temp/modemmanager" "ModemManager-$MM_COMMIT" "$MM_COMMIT" @@ -239,12 +235,28 @@ systemd = always extra_packages = soc-fairphone-fp6-audio,callaudioshim,imsd,fingerprintd,fingerprintd-systemd,fingerprintd-agent,fp6-device-tweaks,fp6-charging-mode,catcrafts-fp6-repo,postmarketos-base-ui-audio-backend-pipewire,pipewire-pulse,pipewire-echo-cancel$UI_PACKAGES EOF -# All four source tarballs are generated locally above, so every checksum +# The local package repository under $WORKDIR is consulted before every +# other repository. Whether it survives from one CI run to the next is not +# established (run 60 rebuilt the packages run 58 had built, which says it +# did not), but nothing guarantees it either way, and a package nobody builds +# any more would win over Alpine's in the builds and in the images: the +# libqmi fork, retired 2026-10-12, as 1.39.1_git20260808. Delete its apks +# from every channel and rebuild the index from the files present (an index +# naming missing apks fails the next apk run), then make sure none is left. pmbootstrap's own 'zap --pkgs-local-mismatch' is no use here: +# with systemd selected it reads packages/systemd-edge, while the builds +# land in packages/edge. The dir belongs to the chroot uid (see 3b). +if [ -d "$WORKDIR/packages" ]; then + sudo find "$WORKDIR/packages" -name '*.apk' \( -name 'libqmi-*' -o -name 'qmi-utils-*' \) -delete + retry "re-index local packages" pmbootstrap index + left=$(sudo find "$WORKDIR/packages" -name '*.apk' \( -name 'libqmi-*' -o -name 'qmi-utils-*' \)) + [ -z "$left" ] || { echo "retired libqmi fork still in the local repository:" >&2; echo "$left" >&2; exit 1; } +fi + +# All three source tarballs are generated locally above, so every checksum # step is offline. libcamera needs a checksum step now too: its committed # sums were for the fd.o-served tarball, and git-archive output is not # byte-identical to it (verified: sha512 differs). pmbootstrap checksum linux-postmarketos-qcom-milos -pmbootstrap checksum libqmi pmbootstrap checksum modemmanager pmbootstrap checksum libcamera @@ -255,11 +267,8 @@ pmbootstrap checksum libcamera # kernel is unaffected either way (cross-native, no crossdirect). NOCROSS=${FP6IMG_NO_CROSSDIRECT:+--no-cross} -# pmbootstrap's install-time build plan is not dependency-ordered (it tried -# building modemmanager before the libqmi its makedepends require); build -# the GNSS stack bottom-up explicitly. 'pmbootstrap build' is a no-op when -# the package is already current. -retry "build libqmi" pmbootstrap $NOCROSS build --arch aarch64 libqmi +# Build the patched packages explicitly ('pmbootstrap build' is a no-op when +# the package is already current). retry "build modemmanager" pmbootstrap $NOCROSS build --arch aarch64 modemmanager # libcamera is no makedepend of anything here - build it explicitly so the # patched -r2 exists for the publish step even if the install set resolves From 9456e5092ff1a7d17c9d0c388ce2f7e15b186e1d Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Mon, 12 Oct 2026 01:17:32 +0200 Subject: [PATCH 4/7] fp6-img-plasma: both images are named after their shell The Plasma Mobile archive was fp6-img.tar.xz and the Phosh one fp6-img-phosh.tar.xz, so the unmarked one looked like the only one. Both are now fp6-img-.tar.xz and extract to a directory of that name; install.sh's messages and the README say so, and the README names the dialer each shell calls with. The release upload takes dist/* and needs no change. --- .forgejo/workflows/build.yml | 4 ++-- README.md | 13 +++++-------- build.sh | 6 +++--- install.sh | 11 ++++++----- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 2046b11..3af50cf 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -1,7 +1,7 @@ name: image # Builds the flashable postmarketOS images for the Fairphone 6 (kernel from -# milos-linux combined-stable + imsd) — Plasma Mobile (fp6-img.tar.xz) and +# milos-linux combined-stable + imsd) — Plasma Mobile (fp6-img-plasma.tar.xz) and # Phosh (fp6-img-phosh.tar.xz) — and publishes both as the rolling 'latest' # release. # @@ -40,7 +40,7 @@ jobs: # Second UI from the same package builds (the kernel and the aports # above are already current in pmbootstrap's work dir, so this is the - # install + export only): fp6-img-phosh.tar.xz next to fp6-img.tar.xz + # install + export only): fp6-img-phosh.tar.xz next to fp6-img-plasma.tar.xz # in the same release. - name: Build image (Phosh) run: FP6IMG_UI=phosh FP6IMG_KEEP_DIST=1 ./build.sh diff --git a/README.md b/README.md index aa8ee72..dd4fb70 100644 --- a/README.md +++ b/README.md @@ -20,22 +20,19 @@ VoLTE calls (both directions) through imsd. ## Flashing -Download `fp6-img.tar.xz` from the latest release and unlock the bootloader +Download `fp6-img-{DE}.tar.xz` with your preferred DE from the latest release +(`{DE}` is `plasma` for Plasma Mobile, calls through Plasma Dialer, or `phosh` for +Phosh, calls through GNOME Calls) and unlock the bootloader ([Fairphone's official process](https://support.fairphone.com/hc/en-us/articles/10492476238737)). **Install**: with the phone in fastboot mode, ```sh -tar xf fp6-img.tar.xz -cd fp6-img +tar xf fp6-img-{DE}.tar.xz +cd fp6-img-{DE} ./install.sh ``` -Two images are published per release, same kernel and packages, different -shell: `fp6-img.tar.xz` boots **Plasma Mobile** (calls through Plasma -Dialer), `fp6-img-phosh.tar.xz` boots **Phosh** (calls through GNOME Calls, -via imsd's `imsd-ofono` backend). Pick one; the install steps are identical. - `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`. diff --git a/build.sh b/build.sh index 6852a95..4aabd3c 100755 --- a/build.sh +++ b/build.sh @@ -35,11 +35,11 @@ REGISTRY=https://forgejo.catcrafts.net/api/packages/Catcrafts/alpine/edge/fp6 # opt-in imsd-ofono subpackage (imsd-ofonod + the GNOME Calls plugin # override) and fp6-login-screen-schema (GNOME Settings' fingerprint row) on # top. Everything else in the package set is UI-agnostic. The -# archive is named after it: fp6-img.tar.xz for plasma-mobile, -# fp6-img-.tar.xz otherwise, so one release can carry both. +# archive is named after it: fp6-img-plasma.tar.xz for plasma-mobile, +# fp6-img-phosh.tar.xz for phosh, so one release can carry both. FP6IMG_UI=${FP6IMG_UI:-plasma-mobile} case "$FP6IMG_UI" in -plasma-mobile) UI_PACKAGES=; IMG_NAME=fp6-img ;; +plasma-mobile) UI_PACKAGES=; IMG_NAME=fp6-img-plasma ;; phosh) UI_PACKAGES=,imsd-ofono,fp6-login-screen-schema; IMG_NAME=fp6-img-phosh ;; *) echo "FP6IMG_UI=$FP6IMG_UI: expected plasma-mobile or phosh" >&2; exit 1 ;; esac diff --git a/install.sh b/install.sh index 1e20126..3034d4c 100755 --- a/install.sh +++ b/install.sh @@ -18,7 +18,8 @@ # Requirements on this machine: fastboot, ssh. Phone: bootloader unlocked, # in fastboot mode (Vol-down + Power), connected over USB. # Run from the directory the release archive extracts to: -# tar xf fp6-img.tar.xz && cd fp6-img && ./install.sh +# tar xf fp6-img-plasma.tar.xz && cd fp6-img-plasma && ./install.sh +# (or the fp6-img-phosh archive) PHONE=172.16.42.1 BOOT=${BOOT:-boot.img} @@ -30,10 +31,10 @@ die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; } # --- preflight --------------------------------------------------------------- command -v fastboot >/dev/null || die "fastboot not found (install android-tools)" command -v ssh >/dev/null || die "ssh not found" -[ -f "$BOOT" ] || die "$BOOT not found - run this from the extracted fp6-img - directory (tar xf fp6-img.tar.xz && cd fp6-img)" -[ -f "$ROOTFS" ] || die "$ROOTFS not found - run this from the extracted fp6-img - directory (tar xf fp6-img.tar.xz && cd fp6-img)" +[ -f "$BOOT" ] || die "$BOOT not found - run this from the extracted release + directory (tar xf fp6-img-plasma.tar.xz && cd fp6-img-plasma, or the phosh one)" +[ -f "$ROOTFS" ] || die "$ROOTFS not found - run this from the extracted release + directory (tar xf fp6-img-plasma.tar.xz && cd fp6-img-plasma, or the phosh one)" # NEVER pipe fastboot into grep -q or anything that exits early: the reader # quitting mid-output SIGPIPEs fastboot to death mid-transaction and leaves # the bootloader's fastboot state machine wedged - the NEXT command then From a13925a1dc73f744c825d822a965208bce5beae2 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Mon, 12 Oct 2026 01:17:32 +0200 Subject: [PATCH 5/7] README, install.sh: imsd 1.0.0 finds the P-CSCF itself, the setup section goes imsd 1.0.0 reads the carrier's P-CSCF from the ims PDN at every start, so the section that had every user find it with adb and write /etc/imsd.env goes, as does install.sh's closing hint; the file remains for overriding the address or naming one where the network gives none. The intro no longer presents imsd as a preinstalled extra; it is linked where VoLTE is listed. --- README.md | 21 ++------------------- install.sh | 3 +-- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index dd4fb70..ee6d61b 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,7 @@ Flashable [postmarketOS](https://postmarketos.org/) images for the **Fairphone 6/6+**, built nightly from the [Catcrafts milos-linux](https://forgejo.catcrafts.net/Catcrafts/milos-linux) -`combined-stable` kernel branch, with -[imsd](https://forgejo.catcrafts.net/Catcrafts/imsd) (userspace VoLTE) -preinstalled. +`combined-stable` kernel branch. Maintained by [Jorijn van der Graaf](https://catcrafts.net/about) (TheMightyCat) at [Catcrafts](https://catcrafts.net/). @@ -16,7 +14,7 @@ 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](https://forgejo.catcrafts.net/Catcrafts/fingerprintd), plus -VoLTE calls (both directions) through imsd. +VoLTE calls (both directions) through [imsd](https://forgejo.catcrafts.net/Catcrafts/imsd). ## Flashing @@ -39,18 +37,3 @@ 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: - -```sh -# /etc/imsd.env -PCSCF= -``` - -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](https://forgejo.catcrafts.net/Catcrafts/imsd) for the full -variable reference and carrier assumptions. diff --git a/install.sh b/install.sh index 3034d4c..b34d90c 100755 --- a/install.sh +++ b/install.sh @@ -167,6 +167,5 @@ ssh $SSHOPTS -O exit "user@$PHONE" 2>/dev/null || true cat <<'EOF' DONE. The phone reboots into postmarketOS from its own boot partition. -Log in as user / 147147. For VoLTE, write your carrier's -P-CSCF into /etc/imsd.env and restart imsd - see the README. +Log in as user / 147147. EOF From ac71acd20ee1889fa0205c3b5393de136f5dca00 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Wed, 14 Oct 2026 01:41:43 +0200 Subject: [PATCH 6/7] README: link the latest release Release notes become dated releases of their own on the releases page, notes only, while the images stay in 'latest'; the download line names the 'latest' release by its link. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ee6d61b..eab56b2 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ VoLTE calls (both directions) through [imsd](https://forgejo.catcrafts.net/Catcr ## Flashing -Download `fp6-img-{DE}.tar.xz` with your preferred DE from the latest release +Download `fp6-img-{DE}.tar.xz` with your preferred DE from the +[`latest` release](https://forgejo.catcrafts.net/Catcrafts/fp6-img/releases/tag/latest) (`{DE}` is `plasma` for Plasma Mobile, calls through Plasma Dialer, or `phosh` for Phosh, calls through GNOME Calls) and unlock the bootloader ([Fairphone's official process](https://support.fairphone.com/hc/en-us/articles/10492476238737)). From 2c317d9e2e094aab93e0f78ee635575a802e6629 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Mon, 12 Oct 2026 15:51:36 +0200 Subject: [PATCH 7/7] the images follow the upstream rename: postmarketOS is Nura postmarketOS renamed itself Nura on 2026-09-27 (https://nura.eco/blog/2026/09/27/nura-rename/). The README intro, install.sh's messages, the 'latest' release title, the build headers and the default-login lines now say so. Identifiers keep their names - package names, the pmaports and mirror URLs, pmbootstrap - until upstream moves them. The intro also stops calling the images nightly: the schedule trigger is commented out, CI builds on push. --- .forgejo/workflows/build.yml | 4 ++-- README.md | 6 +++--- build.sh | 8 ++++---- install.sh | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 3af50cf..c5eccf6 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -1,6 +1,6 @@ name: image -# Builds the flashable postmarketOS images for the Fairphone 6 (kernel from +# Builds the flashable Nura images for the Fairphone 6 (kernel from # milos-linux combined-stable + imsd) — Plasma Mobile (fp6-img-plasma.tar.xz) and # Phosh (fp6-img-phosh.tar.xz) — and publishes both as the rolling 'latest' # release. @@ -106,7 +106,7 @@ jobs: url: ${{ github.server_url }} repo: ${{ github.repository }} tag: latest - title: Latest FP6 postmarketOS image + title: Latest FP6 Nura image prerelease: true override: true release-dir: dist diff --git a/README.md b/README.md index eab56b2..9380819 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # fp6-img -Flashable [postmarketOS](https://postmarketos.org/) images for the -**Fairphone 6/6+**, built nightly from the +Flashable [Nura](https://nura.eco) images for the +**Fairphone 6/6+**, built from the [Catcrafts milos-linux](https://forgejo.catcrafts.net/Catcrafts/milos-linux) `combined-stable` kernel branch. @@ -36,5 +36,5 @@ cd fp6-img-{DE} 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). +Default login: `user` / `147147` (same as official Nura images). **Never re-lock the bootloader** with a custom image installed. diff --git a/build.sh b/build.sh index 4aabd3c..b351667 100755 --- a/build.sh +++ b/build.sh @@ -1,5 +1,5 @@ #!/bin/sh -eu -# fp6-img pipeline: build a flashable postmarketOS image for the Fairphone 6 +# fp6-img pipeline: build a flashable Nura image for the Fairphone 6 # with the Catcrafts kernel (milos-linux combined-stable), imsd (VoLTE) and # fingerprintd (fingerprint unlock) # installed from the Catcrafts apk registry. @@ -30,7 +30,7 @@ KERNEL_BRANCH=combined-stable # sha256; that gated fresh installs only, never upgrades, and cost a commit # and an image run per release. REGISTRY=https://forgejo.catcrafts.net/api/packages/Catcrafts/alpine/edge/fp6 -# FP6IMG_UI: which postmarketOS UI the image boots into. plasma-mobile (the +# FP6IMG_UI: which Nura UI the image boots into. plasma-mobile (the # default) gets imsd-dialerd from the imsd package itself; phosh gets the # opt-in imsd-ofono subpackage (imsd-ofonod + the GNOME Calls plugin # override) and fp6-login-screen-schema (GNOME Settings' fingerprint row) on @@ -330,7 +330,7 @@ rm -f "$REG_DL"/*.apk pmbootstrap index # --- 4. build the image ------------------------------------------------------- -# Same default credentials as the official postmarketOS images. +# Same default credentials as the official Nura images. pmbootstrap -y zap >/dev/null 2>&1 || true pmbootstrap install --password 147147 @@ -358,7 +358,7 @@ cp README.md install.sh "$STAGE/$IMG_NAME/" echo "kernel: $KERNEL_REPO $KERNEL_BRANCH @ $COMMIT" echo "ui: $FP6IMG_UI" echo "built: $(date -u +%Y-%m-%dT%H:%M:%SZ)" - echo "default login: user / 147147 (same as official postmarketOS images)" + echo "default login: user / 147147 (same as official Nura images)" while read -r _n _v _s; do printf '%-14s %s %s-%s (newest registry package, sha256 %s)\n' "$_n:" "$REGISTRY" "$_n" "$_v" "$_s" done < "$REG_DL/manifest" diff --git a/install.sh b/install.sh index b34d90c..ac5d53f 100755 --- a/install.sh +++ b/install.sh @@ -50,7 +50,7 @@ printf '%s' "$DEVINFO" | grep -q "Device unlocked: true" || \ then re-run. Note that unlocking wipes the phone." cat <<'EOF' -This will replace the operating system on the connected Fairphone 6 with catcrafts patched postmarketos. Keep the phone connected on USB for the entirety of this script's duration. +This will replace the operating system on the connected Fairphone 6 with the Catcrafts build of Nura. Keep the phone connected on USB for the entirety of this script's duration. If this has been usefull please consider donating at https://catcrafts.net/shop/donation WARNING: This is a early version of the install script for power users ahead of the official release, while tested this has not been trough the strict quality control the offical release will have. Press Enter to continue, Ctrl-C to abort. @@ -151,7 +151,7 @@ Z=$(ssh $SSHOPTS "user@$PHONE" \ if [ "$Z" -le 2 ]; then cat <<'EOF' WARNING: the modem NV reads empty. If this device previously ran stock -Android, its factory copy (fsg) is still on the device but postmarketOS +Android, its factory copy (fsg) is still on the device but Nura cannot restore from it yet - see the README's modem section. If you have a modemst backup, dd it back now. EOF @@ -166,6 +166,6 @@ ssh $SSHOPTS -O exit "user@$PHONE" 2>/dev/null || true cat <<'EOF' -DONE. The phone reboots into postmarketOS from its own boot partition. +DONE. The phone reboots into Nura from its own boot partition. Log in as user / 147147. EOF