Compare commits

..
11 changed files with 172 additions and 92 deletions

View file

@ -1,7 +1,7 @@
name: image name: image
# Builds the flashable Nura images for the Fairphone 6 (kernel from # Builds the flashable postmarketOS images for the Fairphone 6 (kernel from
# milos-linux combined-stable + imsd) — Plasma Mobile (fp6-img-plasma.tar.xz) and # milos-linux combined-stable + imsd) — Plasma Mobile (fp6-img.tar.xz) and
# Phosh (fp6-img-phosh.tar.xz) — and publishes both as the rolling 'latest' # Phosh (fp6-img-phosh.tar.xz) — and publishes both as the rolling 'latest'
# release. # release.
# #
@ -40,7 +40,7 @@ jobs:
# Second UI from the same package builds (the kernel and the aports # 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 # 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-plasma.tar.xz # install + export only): fp6-img-phosh.tar.xz next to fp6-img.tar.xz
# in the same release. # in the same release.
- name: Build image (Phosh) - name: Build image (Phosh)
run: FP6IMG_UI=phosh FP6IMG_KEEP_DIST=1 ./build.sh run: FP6IMG_UI=phosh FP6IMG_KEEP_DIST=1 ./build.sh
@ -52,17 +52,14 @@ jobs:
path: dist/* path: dist/*
if-no-files-found: error if-no-files-found: error
# Ship every locally built apk (kernel, modemmanager, callaudioshim, # Ship every locally built apk (kernel, modemmanager, libqmi,
# audio files, ...) to the Forgejo Alpine registry, so # callaudioshim, audio files, ...) to the Forgejo Alpine registry, so
# installed systems get updates via 'apk upgrade' instead of losing # installed systems get updates via 'apk upgrade' instead of losing
# the FP6 patches to the next upstream version bump. Requires the # the FP6 patches to the next upstream version bump. Requires the
# PACKAGE_TOKEN repo secret (catbot account, package:write scope); # PACKAGE_TOKEN repo secret (catbot account, package:write scope);
# skips quietly until it exists. 409 = same version already published. # skips quietly until it exists. 409 = same version already published.
# imsd and fingerprintd are skipped: build.sh 3b took them FROM the # 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. # 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 - name: Publish packages to the apk registry
env: env:
PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }} PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
@ -77,7 +74,6 @@ jobs:
[ -e "$f" ] || continue [ -e "$f" ] || continue
case "$(basename "$f")" in case "$(basename "$f")" in
imsd-*|fingerprintd-*) echo "registry-sourced, not republished: $(basename "$f")"; continue ;; imsd-*|fingerprintd-*) echo "registry-sourced, not republished: $(basename "$f")"; continue ;;
libqmi-*|qmi-utils-*) echo "retired fork, not republished: $(basename "$f")"; continue ;;
esac esac
found=1 found=1
code=$(curl -s -o /dev/null -w '%{http_code}' \ code=$(curl -s -o /dev/null -w '%{http_code}' \
@ -106,7 +102,7 @@ jobs:
url: ${{ github.server_url }} url: ${{ github.server_url }}
repo: ${{ github.repository }} repo: ${{ github.repository }}
tag: latest tag: latest
title: Latest FP6 Nura image title: Latest FP6 postmarketOS image
prerelease: true prerelease: true
override: true override: true
release-dir: dist release-dir: dist

View file

@ -1,9 +1,11 @@
# fp6-img # fp6-img
Flashable [Nura](https://nura.eco) images for the Flashable [postmarketOS](https://postmarketos.org/) images for the
**Fairphone 6/6+**, built from the **Fairphone 6/6+**, built nightly from the
[Catcrafts milos-linux](https://forgejo.catcrafts.net/Catcrafts/milos-linux) [Catcrafts milos-linux](https://forgejo.catcrafts.net/Catcrafts/milos-linux)
`combined-stable` kernel branch. `combined-stable` kernel branch, with
[imsd](https://forgejo.catcrafts.net/Catcrafts/imsd) (userspace VoLTE)
preinstalled.
Maintained by [Jorijn van der Graaf](https://catcrafts.net/about) Maintained by [Jorijn van der Graaf](https://catcrafts.net/about)
(TheMightyCat) at [Catcrafts](https://catcrafts.net/). (TheMightyCat) at [Catcrafts](https://catcrafts.net/).
@ -14,27 +16,44 @@ Everything on the `combined-stable` branch: display, touch, wifi, cellular
data, NFC (reader), speaker audio, microphone, IMU, magnetometer, barometer, data, NFC (reader), speaker audio, microphone, IMU, magnetometer, barometer,
ambient light/proximity, fingerprint unlock through ambient light/proximity, fingerprint unlock through
[fingerprintd](https://forgejo.catcrafts.net/Catcrafts/fingerprintd), plus [fingerprintd](https://forgejo.catcrafts.net/Catcrafts/fingerprintd), plus
VoLTE calls (both directions) through [imsd](https://forgejo.catcrafts.net/Catcrafts/imsd). VoLTE calls (both directions) through imsd.
## Flashing ## Flashing
Download `fp6-img-{DE}.tar.xz` with your preferred DE from the Download `fp6-img.tar.xz` from the latest release and unlock the bootloader
[`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)). ([Fairphone's official process](https://support.fairphone.com/hc/en-us/articles/10492476238737)).
**Install**: with the phone in fastboot mode, **Install**: with the phone in fastboot mode,
```sh ```sh
tar xf fp6-img-{DE}.tar.xz tar xf fp6-img.tar.xz
cd fp6-img-{DE} cd fp6-img
./install.sh ./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 `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 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`. NV back and reports the result. The bootloader never writes `boot`.
Default login: `user` / `147147` (same as official Nura images). Default login: `user` / `147147` (same as official postmarketOS images).
**Never re-lock the bootloader** with a custom image installed. **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=<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](https://forgejo.catcrafts.net/Catcrafts/imsd) for the full
variable reference and carrier assumptions.

View file

@ -1,7 +1,7 @@
# Enables the Catcrafts FP6 package repository on the installed system: # Enables the Catcrafts FP6 package repository on the installed system:
# installs the Forgejo package-registry signing key and appends the repo URL # installs the Forgejo package-registry signing key and appends the repo URL
# to /etc/apk/repositories. With this, 'apk upgrade' pulls the CI-published # to /etc/apk/repositories. With this, 'apk upgrade' pulls the CI-published
# kernel/modemmanager/imsd builds instead of losing the FP6 patches # kernel/modemmanager/libqmi/imsd builds instead of losing the FP6 patches
# to the next upstream version bump. # to the next upstream version bump.
maintainer="Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>" maintainer="Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>"
pkgname=catcrafts-fp6-repo pkgname=catcrafts-fp6-repo

View file

@ -20,7 +20,7 @@
maintainer="Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>" maintainer="Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>"
pkgname=fp6-device-tweaks pkgname=fp6-device-tweaks
pkgver=5 pkgver=5
pkgrel=1 pkgrel=0
pkgdesc="Fairphone 6 device-critical system configuration" pkgdesc="Fairphone 6 device-critical system configuration"
url="https://forgejo.catcrafts.net/Catcrafts/fp6-img" url="https://forgejo.catcrafts.net/Catcrafts/fp6-img"
arch="noarch" arch="noarch"
@ -58,7 +58,7 @@ package() {
sha512sums=" sha512sums="
5e60fef47cb09cec7cab73464183dfd9e9cb32cebd1d20a67922c10c5a747eca8d106b66737d06af5c5c162a6baf37ab62a82709cc20911044face100d482919 inv-icm42600.conf 5e60fef47cb09cec7cab73464183dfd9e9cb32cebd1d20a67922c10c5a747eca8d106b66737d06af5c5c162a6baf37ab62a82709cc20911044face100d482919 inv-icm42600.conf
cc13f6abc4538fef976c59893992dd2c193cd0eac5da37a9fb01ba421b3ba8ff303aa438ec2fe4d10f50165f90be211d4b2c39dc6ef58d0d320fba8182ccf287 81-fp6-accel-poll.rules cc13f6abc4538fef976c59893992dd2c193cd0eac5da37a9fb01ba421b3ba8ff303aa438ec2fe4d10f50165f90be211d4b2c39dc6ef58d0d320fba8182ccf287 81-fp6-accel-poll.rules
f74c6c5d0ba3015cf123808452e9677c1d087e9540ea7037c30316e48a5c5bbdafe712ff0b07f17969337b1576a34cdfef4319c464ffe38c092a67d313129b57 iio-sensor-proxy-restart.conf 1800ad5c11b4e38c10b0c72b2392a6dc978a4e37bcd964182adb90d7d9aa7afc74acf102e2051dbf864021c05821f683af8943e2729e1eaa195856a0bd635e09 iio-sensor-proxy-restart.conf
8fec832be59ca616d3e6a4c0a5ef8067d25f767c79155d8b0ef5761b8d21532932235a3236807305937029efe6255a16696d05523e3e654e2dc2212a281fe12c modem-gnss-nmea-optional.conf 8fec832be59ca616d3e6a4c0a5ef8067d25f767c79155d8b0ef5761b8d21532932235a3236807305937029efe6255a16696d05523e3e654e2dc2212a281fe12c modem-gnss-nmea-optional.conf
1c5fd4a5a2a2c19165dca1381c8c6550fb61c6311561be450c9c6f88046d7649e4c7c6f4a86b163a2ecc1ef5ec93cc1dac1e2aded933a6b3d6d68292a1b609d0 91-fp6-no-ssc-sensors.rules 1c5fd4a5a2a2c19165dca1381c8c6550fb61c6311561be450c9c6f88046d7649e4c7c6f4a86b163a2ecc1ef5ec93cc1dac1e2aded933a6b3d6d68292a1b609d0 91-fp6-no-ssc-sensors.rules
" "

View file

@ -1,6 +1,5 @@
# Generic on-failure safety net. The boot-time libssc crash this was written # Revive after the known boot-time libssc crash (unconfigured SSC);
# for (2026-07-20, recreated 2026-07-28) is prevented by # recreated 2026-07-28 - the 2026-07-20 drop-in had gone missing.
# 91-fp6-no-ssc-sensors.rules since fp6-device-tweaks 5.
[Unit] [Unit]
StartLimitIntervalSec=0 StartLimitIntervalSec=0
[Service] [Service]

View file

@ -0,0 +1,77 @@
# 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 <developer@it-offshore.co.uk>
maintainer="Achill Gilgenast <achill@achill.org>"
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
"

View file

@ -1,7 +1,7 @@
From d9e93ad09b75ec2813a01bbb07794a5c85a3a56d Mon Sep 17 00:00:00 2001 From 2924dab906b3dc9e3b48e766637618ce53615c23 Mon Sep 17 00:00:00 2001
From: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net> From: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Date: Thu, 2 Jul 2026 15:30:48 +0200 Date: Thu, 2 Jul 2026 15:30:48 +0200
Subject: [PATCH] shared-qmi: unlock AFW-gated GNSS engines at LOC start Subject: [PATCH 2/3] shared-qmi: unlock AFW-gated GNSS engines at LOC start
Newer Snapdragon GNSS engines (e.g. gnss8 in the SM7635/Fairphone 6) Newer Snapdragon GNSS engines (e.g. gnss8 in the SM7635/Fairphone 6)
only allow positioning for clients registered as application framework only allow positioning for clients registered as application framework
@ -44,10 +44,10 @@ Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
2 files changed, 86 insertions(+), 55 deletions(-) 2 files changed, 86 insertions(+), 55 deletions(-)
diff --git a/meson.build b/meson.build diff --git a/meson.build b/meson.build
index 9b8ab2d1..1bb10b94 100644 index 3cf29e80..e5e3d0be 100644
--- a/meson.build --- a/meson.build
+++ b/meson.build +++ b/meson.build
@@ -297,7 +297,7 @@ config_h.set('WITH_MBIM', enable_mbim) @@ -277,7 +277,7 @@ config_h.set('WITH_MBIM', enable_mbim)
# QMI support (enabled by default) # QMI support (enabled by default)
enable_qmi = get_option('qmi') enable_qmi = get_option('qmi')
if enable_qmi if enable_qmi
@ -57,10 +57,10 @@ index 9b8ab2d1..1bb10b94 100644
if not qmi_glib_dep.found() and get_option('subproject-fallback') 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 diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c
index f578d876..25990ceb 100644 index d93698a6..09aa987a 100644
--- a/src/mm-shared-qmi.c --- a/src/mm-shared-qmi.c
+++ b/src/mm-shared-qmi.c +++ b/src/mm-shared-qmi.c
@@ -5652,33 +5652,67 @@ pds_gps_service_state_start_ready (QmiClientPds *client, @@ -5646,33 +5646,67 @@ pds_gps_service_state_start_ready (QmiClientPds *client,
qmi_message_pds_set_auto_tracking_state_input_unref (input); qmi_message_pds_set_auto_tracking_state_input_unref (input);
} }
@ -142,7 +142,7 @@ index f578d876..25990ceb 100644
self = g_task_get_source_object (task); self = g_task_get_source_object (task);
priv = get_private (self); priv = get_private (self);
@@ -5697,16 +5731,16 @@ loc_register_events_ready (QmiClientLoc *client, @@ -5691,16 +5725,16 @@ loc_register_events_ready (QmiClientLoc *client,
} }
static void static void
@ -167,7 +167,7 @@ index f578d876..25990ceb 100644
if (!output) { if (!output) {
g_prefix_error (&error, "QMI operation failed: "); g_prefix_error (&error, "QMI operation failed: ");
g_task_return_error (task, error); g_task_return_error (task, error);
@@ -5714,32 +5748,40 @@ loc_start_ready (QmiClientLoc *client, @@ -5708,32 +5742,40 @@ loc_start_ready (QmiClientLoc *client,
return; return;
} }
@ -226,7 +226,7 @@ index f578d876..25990ceb 100644
static void static void
start_gps_engine (MMSharedQmi *self, start_gps_engine (MMSharedQmi *self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
@@ -5777,20 +5819,9 @@ start_gps_engine (MMSharedQmi *self, @@ -5771,20 +5813,9 @@ start_gps_engine (MMSharedQmi *self,
MM_PORT_QMI_FLAG_DEFAULT, MM_PORT_QMI_FLAG_DEFAULT,
NULL); NULL);
if (client) { if (client) {

View file

@ -1,7 +1,8 @@
From 59f2f17246a844e07569e2ee6523c810364e1e52 Mon Sep 17 00:00:00 2001 From 7566587e77d299ab0f67613ae03cab9973e351db Mon Sep 17 00:00:00 2001
From: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net> From: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Date: Thu, 2 Jul 2026 15:44:16 +0200 Date: Thu, 2 Jul 2026 15:44:16 +0200
Subject: [PATCH] shared-qmi: derive location from Position Report indications Subject: [PATCH 3/3] shared-qmi: derive location from Position Report
indications
Some GNSS engines (e.g. gnss8 in the SM7635/Fairphone 6) report fixes 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 only via QMI_LOC Position Report indications and never emit NMEA (Set
@ -42,7 +43,7 @@ Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
1 file changed, 147 insertions(+) 1 file changed, 147 insertions(+)
diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c
index 25990ceb..d2eefb26 100644 index 09aa987a..cad75080 100644
--- a/src/mm-shared-qmi.c --- a/src/mm-shared-qmi.c
+++ b/src/mm-shared-qmi.c +++ b/src/mm-shared-qmi.c
@@ -88,6 +88,8 @@ typedef struct { @@ -88,6 +88,8 @@ typedef struct {
@ -63,7 +64,7 @@ index 25990ceb..d2eefb26 100644
if (priv->loc_assistance_inject_time_req_indication_id) if (priv->loc_assistance_inject_time_req_indication_id)
g_signal_handler_disconnect (priv->loc_client, 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) if (priv->loc_assistance_inject_position_req_indication_id)
@@ -5167,6 +5171,10 @@ loc_stop_ready (QmiClientLoc *client, @@ -5161,6 +5165,10 @@ loc_stop_ready (QmiClientLoc *client,
g_signal_handler_disconnect (priv->loc_client, priv->loc_location_nmea_indication_id); g_signal_handler_disconnect (priv->loc_client, priv->loc_location_nmea_indication_id);
priv->loc_location_nmea_indication_id = 0; priv->loc_location_nmea_indication_id = 0;
} }
@ -74,7 +75,7 @@ index 25990ceb..d2eefb26 100644
g_clear_object (&priv->loc_client); g_clear_object (&priv->loc_client);
} }
@@ -5270,11 +5278,142 @@ loc_location_nmea_indication_cb (QmiClientLoc *client, @@ -5264,11 +5272,142 @@ loc_location_nmea_indication_cb (QmiClientLoc *client,
if (!nmea) if (!nmea)
return; return;
@ -217,7 +218,7 @@ index 25990ceb..d2eefb26 100644
/*****************************************************************************/ /*****************************************************************************/
/* Location: internal helper: setup minimum required NMEA traces */ /* Location: internal helper: setup minimum required NMEA traces */
@@ -5668,6 +5807,7 @@ gps_engine_loc_register_events (QmiClientLoc *client, @@ -5662,6 +5801,7 @@ gps_engine_loc_register_events (QmiClientLoc *client,
guint64 event_mask; guint64 event_mask;
event_mask = QMI_LOC_EVENT_REGISTRATION_FLAG_NMEA | event_mask = QMI_LOC_EVENT_REGISTRATION_FLAG_NMEA |
@ -225,7 +226,7 @@ index 25990ceb..d2eefb26 100644
QMI_LOC_EVENT_REGISTRATION_FLAG_INJECT_TIME_REQUEST | QMI_LOC_EVENT_REGISTRATION_FLAG_INJECT_TIME_REQUEST |
QMI_LOC_EVENT_REGISTRATION_FLAG_INJECT_POSITION_REQUEST; QMI_LOC_EVENT_REGISTRATION_FLAG_INJECT_POSITION_REQUEST;
input = qmi_message_loc_register_events_input_new (); input = qmi_message_loc_register_events_input_new ();
@@ -5719,12 +5859,19 @@ loc_start_ready (QmiClientLoc *client, @@ -5713,12 +5853,19 @@ loc_start_ready (QmiClientLoc *client,
g_assert (!priv->loc_client); g_assert (!priv->loc_client);
g_assert (!priv->loc_location_nmea_indication_id); g_assert (!priv->loc_location_nmea_indication_id);

View file

@ -1,15 +1,12 @@
# fp6-img fork of Alpine community/modemmanager: + the AFW-gated GNSS # fp6-img fork of Alpine community/modemmanager: + the AFW-gated GNSS
# engine unlock + Position Report location derivation (upstream MR !1463, # engine unlock + Position Report location derivation (upstream MR !1463,
# still draft) - the other half of working GNSS on the FP6. Snapshot and # still draft) - the other half of working GNSS on the FP6.
# 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 <developer@it-offshore.co.uk> # Contributor: Stuart Cardall <developer@it-offshore.co.uk>
maintainer="Achill Gilgenast <achill@achill.org>" maintainer="Achill Gilgenast <achill@achill.org>"
pkgname=modemmanager pkgname=modemmanager
pkgver=1.25.95_git20261005 pkgver=1.25.95_git20260709
pkgrel=101 pkgrel=101
_commit=7f0bf17ab518cd78925cf7e53cc0d5c42f88b41a _commit=d776ea38d29ca472a12323c1d45002ee19a66f57
pkgdesc="ModemManager library" pkgdesc="ModemManager library"
url="https://www.freedesktop.org/wiki/Software/ModemManager" url="https://www.freedesktop.org/wiki/Software/ModemManager"
arch="all" arch="all"
@ -32,7 +29,7 @@ makedepends="
gtk-doc gtk-doc
libgudev-dev libgudev-dev
libmbim-dev libmbim-dev
libqmi-dev libqmi-dev>=1.39.1
linux-headers linux-headers
meson meson
polkit-dev polkit-dev
@ -121,7 +118,7 @@ libmm() {
} }
sha512sums=" sha512sums="
fd659330b2ec4e8368807053ec01498241dec153f6f2491bb17c42e2b81c8d9a98ff5f8c153874a6d092e17c545c5ae19734bc23c85c459eb1c7b9b709e5ff58 ModemManager-7f0bf17ab518cd78925cf7e53cc0d5c42f88b41a.tar.gz fd659330b2ec4e8368807053ec01498241dec153f6f2491bb17c42e2b81c8d9a98ff5f8c153874a6d092e17c545c5ae19734bc23c85c459eb1c7b9b709e5ff58 ModemManager-d776ea38d29ca472a12323c1d45002ee19a66f57.tar.gz
6fab86c27502b29be0c6610d835a3249a4a81993eb986cff2c3ea9393fadd3f693ba4bb0532ae0e50a83d359559511859dd05f7ea2f0cb52839f535a7e49f8a0 modemmanager.rules 6fab86c27502b29be0c6610d835a3249a4a81993eb986cff2c3ea9393fadd3f693ba4bb0532ae0e50a83d359559511859dd05f7ea2f0cb52839f535a7e49f8a0 modemmanager.rules
6e234cebcdec6d1afbca164ee5c13c96f7132ef31231d5c043cc5750ebe99e362a384d0463874b3c1c30799b433e0d3286add03af13c97fa406b4b5d2b78880c modemmanager.initd 6e234cebcdec6d1afbca164ee5c13c96f7132ef31231d5c043cc5750ebe99e362a384d0463874b3c1c30799b433e0d3286add03af13c97fa406b4b5d2b78880c modemmanager.initd
f06e9b89acab5b61c5965658d62551b0f168066384674f7c4dd56feb6f811c82c640470e634e32d8c4ef62290588cf974aa5f213e5c67e797a06d33e61fa24ec 0001-intel-XMM7360-fix-big-endian-handling-of-ASN-integer.patch f06e9b89acab5b61c5965658d62551b0f168066384674f7c4dd56feb6f811c82c640470e634e32d8c4ef62290588cf974aa5f213e5c67e797a06d33e61fa24ec 0001-intel-XMM7360-fix-big-endian-handling-of-ASN-integer.patch

View file

@ -1,5 +1,5 @@
#!/bin/sh -eu #!/bin/sh -eu
# fp6-img pipeline: build a flashable Nura image for the Fairphone 6 # fp6-img pipeline: build a flashable postmarketOS image for the Fairphone 6
# with the Catcrafts kernel (milos-linux combined-stable), imsd (VoLTE) and # with the Catcrafts kernel (milos-linux combined-stable), imsd (VoLTE) and
# fingerprintd (fingerprint unlock) # fingerprintd (fingerprint unlock)
# installed from the Catcrafts apk registry. # installed from the Catcrafts apk registry.
@ -30,16 +30,16 @@ KERNEL_BRANCH=combined-stable
# sha256; that gated fresh installs only, never upgrades, and cost a commit # sha256; that gated fresh installs only, never upgrades, and cost a commit
# and an image run per release. # and an image run per release.
REGISTRY=https://forgejo.catcrafts.net/api/packages/Catcrafts/alpine/edge/fp6 REGISTRY=https://forgejo.catcrafts.net/api/packages/Catcrafts/alpine/edge/fp6
# FP6IMG_UI: which Nura UI the image boots into. plasma-mobile (the # FP6IMG_UI: which postmarketOS UI the image boots into. plasma-mobile (the
# default) gets imsd-dialerd from the imsd package itself; phosh gets the # default) gets imsd-dialerd from the imsd package itself; phosh gets the
# opt-in imsd-ofono subpackage (imsd-ofonod + the GNOME Calls plugin # opt-in imsd-ofono subpackage (imsd-ofonod + the GNOME Calls plugin
# override) and fp6-login-screen-schema (GNOME Settings' fingerprint row) on # override) and fp6-login-screen-schema (GNOME Settings' fingerprint row) on
# top. Everything else in the package set is UI-agnostic. The # top. Everything else in the package set is UI-agnostic. The
# archive is named after it: fp6-img-plasma.tar.xz for plasma-mobile, # archive is named after it: fp6-img.tar.xz for plasma-mobile,
# fp6-img-phosh.tar.xz for phosh, so one release can carry both. # fp6-img-<ui>.tar.xz otherwise, so one release can carry both.
FP6IMG_UI=${FP6IMG_UI:-plasma-mobile} FP6IMG_UI=${FP6IMG_UI:-plasma-mobile}
case "$FP6IMG_UI" in case "$FP6IMG_UI" in
plasma-mobile) UI_PACKAGES=; IMG_NAME=fp6-img-plasma ;; plasma-mobile) UI_PACKAGES=; IMG_NAME=fp6-img ;;
phosh) UI_PACKAGES=,imsd-ofono,fp6-login-screen-schema; IMG_NAME=fp6-img-phosh ;; 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 ;; *) echo "FP6IMG_UI=$FP6IMG_UI: expected plasma-mobile or phosh" >&2; exit 1 ;;
esac esac
@ -153,6 +153,7 @@ clone_retry "$WORK/pmaports" -q --depth=1 "$PMAPORTS_REPO"
rm -rf "$WORK/pmaports/device/testing/linux-postmarketos-qcom-milos" \ rm -rf "$WORK/pmaports/device/testing/linux-postmarketos-qcom-milos" \
"$WORK/pmaports/main/postmarketos-config-nftables" \ "$WORK/pmaports/main/postmarketos-config-nftables" \
"$WORK/pmaports/temp/libcamera" \ "$WORK/pmaports/temp/libcamera" \
"$WORK/pmaports/temp/libqmi" \
"$WORK/pmaports/temp/modemmanager" "$WORK/pmaports/temp/modemmanager"
mkdir -p "$WORK/pmaports/temp" mkdir -p "$WORK/pmaports/temp"
cp -r aports/device/linux-postmarketos-qcom-milos "$WORK/pmaports/device/testing/" cp -r aports/device/linux-postmarketos-qcom-milos "$WORK/pmaports/device/testing/"
@ -165,9 +166,9 @@ cp -r aports/device/fp6-charging-mode "$WORK/pmaports/device/"
cp -r aports/device/catcrafts-fp6-repo "$WORK/pmaports/device/" cp -r aports/device/catcrafts-fp6-repo "$WORK/pmaports/device/"
cp -r aports/main/postmarketos-config-nftables "$WORK/pmaports/main/" cp -r aports/main/postmarketos-config-nftables "$WORK/pmaports/main/"
# imsd has no aport here at all: section 3b installs the published apk. # imsd has no aport here at all: section 3b installs the published apk.
# Alpine fork carrying the GNSS patches (MM !1463, draft), built from aports # Alpine forks carrying the GNSS patches (libqmi !470 unreleased; MM !1463
# because r101 > repo. libqmi needs no fork any more: Alpine's snapshot # draft) - deps of modemmanager/imsd, built from aports because r100 > repo.
# (1.38.0_git20261005) is past the !470 merge. cp -r aports/temp/libqmi "$WORK/pmaports/temp/"
cp -r aports/temp/modemmanager "$WORK/pmaports/temp/" cp -r aports/temp/modemmanager "$WORK/pmaports/temp/"
# pmOS libcamera fork + the FP6 OV13B10 sensor-helper/properties patches # pmOS libcamera fork + the FP6 OV13B10 sensor-helper/properties patches
# (r2 > pmOS r1) # (r2 > pmOS r1)
@ -190,7 +191,7 @@ sed -i "s/^_commit=.*/_commit=\"$COMMIT\"/" "$KAPORT/APKBUILD"
KDATE=$(git -C "$WORK/milos-src" log -1 --format=%cd --date=format:%Y%m%d) 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" sed -i "s/^pkgver=\([0-9.]*\)\$/pkgver=\1_git$KDATE/" "$KAPORT/APKBUILD"
# Same dance for the gitlab.freedesktop.org packages (modemmanager, # Same dance for the gitlab.freedesktop.org packages (libqmi, modemmanager,
# libcamera): their pinned tarballs came from fd.o's on-demand archive # 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 # 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 # #31 all died there, outlasting any in-run retry. git clone is served from
@ -208,6 +209,9 @@ fdo_tarball() { # fdo_tarball <repo url> <aport dir> <tarball dirname> <ref>
} }
FDO=https://gitlab.freedesktop.org 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) MM_COMMIT=$(apkbuild_var "$WORK/pmaports/temp/modemmanager" _commit)
fdo_tarball "$FDO/mobile-broadband/ModemManager.git" \ fdo_tarball "$FDO/mobile-broadband/ModemManager.git" \
"$WORK/pmaports/temp/modemmanager" "ModemManager-$MM_COMMIT" "$MM_COMMIT" "$WORK/pmaports/temp/modemmanager" "ModemManager-$MM_COMMIT" "$MM_COMMIT"
@ -235,28 +239,12 @@ 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 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 EOF
# The local package repository under $WORKDIR is consulted before every # All four source tarballs are generated locally above, so every checksum
# 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 # 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 # sums were for the fd.o-served tarball, and git-archive output is not
# byte-identical to it (verified: sha512 differs). # byte-identical to it (verified: sha512 differs).
pmbootstrap checksum linux-postmarketos-qcom-milos pmbootstrap checksum linux-postmarketos-qcom-milos
pmbootstrap checksum libqmi
pmbootstrap checksum modemmanager pmbootstrap checksum modemmanager
pmbootstrap checksum libcamera pmbootstrap checksum libcamera
@ -267,8 +255,11 @@ pmbootstrap checksum libcamera
# kernel is unaffected either way (cross-native, no crossdirect). # kernel is unaffected either way (cross-native, no crossdirect).
NOCROSS=${FP6IMG_NO_CROSSDIRECT:+--no-cross} NOCROSS=${FP6IMG_NO_CROSSDIRECT:+--no-cross}
# Build the patched packages explicitly ('pmbootstrap build' is a no-op when # pmbootstrap's install-time build plan is not dependency-ordered (it tried
# the package is already current). # 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
retry "build modemmanager" pmbootstrap $NOCROSS build --arch aarch64 modemmanager retry "build modemmanager" pmbootstrap $NOCROSS build --arch aarch64 modemmanager
# libcamera is no makedepend of anything here - build it explicitly so the # 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 # patched -r2 exists for the publish step even if the install set resolves
@ -330,7 +321,7 @@ rm -f "$REG_DL"/*.apk
pmbootstrap index pmbootstrap index
# --- 4. build the image ------------------------------------------------------- # --- 4. build the image -------------------------------------------------------
# Same default credentials as the official Nura images. # Same default credentials as the official postmarketOS images.
pmbootstrap -y zap >/dev/null 2>&1 || true pmbootstrap -y zap >/dev/null 2>&1 || true
pmbootstrap install --password 147147 pmbootstrap install --password 147147
@ -358,7 +349,7 @@ cp README.md install.sh "$STAGE/$IMG_NAME/"
echo "kernel: $KERNEL_REPO $KERNEL_BRANCH @ $COMMIT" echo "kernel: $KERNEL_REPO $KERNEL_BRANCH @ $COMMIT"
echo "ui: $FP6IMG_UI" echo "ui: $FP6IMG_UI"
echo "built: $(date -u +%Y-%m-%dT%H:%M:%SZ)" echo "built: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "default login: user / 147147 (same as official Nura images)" echo "default login: user / 147147 (same as official postmarketOS images)"
while read -r _n _v _s; do while read -r _n _v _s; do
printf '%-14s %s %s-%s (newest registry package, sha256 %s)\n' "$_n:" "$REGISTRY" "$_n" "$_v" "$_s" printf '%-14s %s %s-%s (newest registry package, sha256 %s)\n' "$_n:" "$REGISTRY" "$_n" "$_v" "$_s"
done < "$REG_DL/manifest" done < "$REG_DL/manifest"

View file

@ -18,8 +18,7 @@
# Requirements on this machine: fastboot, ssh. Phone: bootloader unlocked, # Requirements on this machine: fastboot, ssh. Phone: bootloader unlocked,
# in fastboot mode (Vol-down + Power), connected over USB. # in fastboot mode (Vol-down + Power), connected over USB.
# Run from the directory the release archive extracts to: # Run from the directory the release archive extracts to:
# tar xf fp6-img-plasma.tar.xz && cd fp6-img-plasma && ./install.sh # tar xf fp6-img.tar.xz && cd fp6-img && ./install.sh
# (or the fp6-img-phosh archive)
PHONE=172.16.42.1 PHONE=172.16.42.1
BOOT=${BOOT:-boot.img} BOOT=${BOOT:-boot.img}
@ -31,10 +30,10 @@ die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; }
# --- preflight --------------------------------------------------------------- # --- preflight ---------------------------------------------------------------
command -v fastboot >/dev/null || die "fastboot not found (install android-tools)" command -v fastboot >/dev/null || die "fastboot not found (install android-tools)"
command -v ssh >/dev/null || die "ssh not found" command -v ssh >/dev/null || die "ssh not found"
[ -f "$BOOT" ] || die "$BOOT not found - run this from the extracted release [ -f "$BOOT" ] || die "$BOOT not found - run this from the extracted fp6-img
directory (tar xf fp6-img-plasma.tar.xz && cd fp6-img-plasma, or the phosh one)" directory (tar xf fp6-img.tar.xz && cd fp6-img)"
[ -f "$ROOTFS" ] || die "$ROOTFS not found - run this from the extracted release [ -f "$ROOTFS" ] || die "$ROOTFS not found - run this from the extracted fp6-img
directory (tar xf fp6-img-plasma.tar.xz && cd fp6-img-plasma, or the phosh one)" directory (tar xf fp6-img.tar.xz && cd fp6-img)"
# NEVER pipe fastboot into grep -q or anything that exits early: the reader # NEVER pipe fastboot into grep -q or anything that exits early: the reader
# quitting mid-output SIGPIPEs fastboot to death mid-transaction and leaves # quitting mid-output SIGPIPEs fastboot to death mid-transaction and leaves
# the bootloader's fastboot state machine wedged - the NEXT command then # the bootloader's fastboot state machine wedged - the NEXT command then
@ -50,7 +49,7 @@ printf '%s' "$DEVINFO" | grep -q "Device unlocked: true" || \
then re-run. Note that unlocking wipes the phone." then re-run. Note that unlocking wipes the phone."
cat <<'EOF' cat <<'EOF'
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. 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.
If this has been usefull please consider donating at https://catcrafts.net/shop/donation 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. 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. Press Enter to continue, Ctrl-C to abort.
@ -151,7 +150,7 @@ Z=$(ssh $SSHOPTS "user@$PHONE" \
if [ "$Z" -le 2 ]; then if [ "$Z" -le 2 ]; then
cat <<'EOF' cat <<'EOF'
WARNING: the modem NV reads empty. If this device previously ran stock WARNING: the modem NV reads empty. If this device previously ran stock
Android, its factory copy (fsg) is still on the device but Nura Android, its factory copy (fsg) is still on the device but postmarketOS
cannot restore from it yet - see the README's modem section. If you have a cannot restore from it yet - see the README's modem section. If you have a
modemst backup, dd it back now. modemst backup, dd it back now.
EOF EOF
@ -166,6 +165,7 @@ ssh $SSHOPTS -O exit "user@$PHONE" 2>/dev/null || true
cat <<'EOF' cat <<'EOF'
DONE. The phone reboots into Nura from its own boot partition. DONE. The phone reboots into postmarketOS from its own boot partition.
Log in as user / 147147. Log in as user / 147147. For VoLTE, write your carrier's
P-CSCF into /etc/imsd.env and restart imsd - see the README.
EOF EOF