fp6-img/aports/device/fp6-vendor-blobs/APKBUILD
Jorijn van der Graaf 9575e5517d fp6-vendor-blobs: reassemble a Qualcomm trustlet, not just copy a file
The fingerprint matcher is a proprietary OEM-signed trustlet, and it is not
shipped as one file: QTEE images live in the modem partition's image/ as an
ELF header+hashes file plus one payload per program header, and the loader
wants each payload written back at its segment's p_offset. So the existing
file directive cannot reach it.

An mbn directive does, with the same guarantees file has: the sha256 is of
the reassembled image, a mismatch tries the next partition, and an unverified
image is never installed. Reassembly is not a concatenation -- segments are
page aligned but not contiguous, gaps stay zero, and two pairs of focal64's
nine segments share an offset, so they are written in index order and the
later one wins, exactly as the bring-up repo's reassemble.py does.

Verified on the dev phone against the hash QTEE has actually accepted since
August: 3600472 bytes, sha256 1930c490..., reassembled from the phone's own
modem_a. The retry path was verified too, with a deliberately wrong first
partition -- which is how the variable clobber got caught: POSIX sh has no
locals, and reassemble() taking rdir= rewrote its caller's copy to the mount
path, so the second partition would have been searched at $MNT/$MNT/...

The fast path needed teaching as well: mbn's dest is the fifth field, and a
first boot would otherwise have exited early and extracted nothing.

Not pushed. The consumer fragment lives in the fingerprintd package.
2026-09-05 03:56:13 +02:00

61 lines
3.2 KiB
Text

# First-boot, on-device extraction of proprietary blobs from the stock
# Android partitions, so the image never has to ship or distribute them.
# pmOS installs flash only boot+userdata: the stock vendor/dsp partitions
# stay on every installed unit, and the device duplicates files it already
# lawfully contains, for its own operation. Design, legal frame and the
# on-phone verification: fp6 repo journal/blobs/.
#
# Consumers depend on this package and install a manifest fragment into
# /usr/share/fp6-vendor-blobs/manifest.d/ (syntax in the extract script);
# their post-install/post-upgrade should also run
# /usr/lib/fp6-vendor-blobs/extract --if-device so a package upgrade that
# drops a previously-shipped blob restores the file immediately instead of
# at the next boot. First consumer: soc-fairphone-fp6-audio (aw88261 acf).
maintainer="Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>"
pkgname=fp6-vendor-blobs
pkgver=1
pkgrel=2
pkgdesc="On-device extraction of vendor blobs from the stock Android partitions"
url="https://forgejo.catcrafts.net/Catcrafts/fp6-img"
arch="noarch"
license="MIT"
# fallback mapper for when the initramfs didn't map the dynamic partitions
depends="make-dynpart-mappings"
install="$pkgname.post-upgrade"
options="!check"
source="
fp6-vendor-blobs-extract
fp6-vendor-blobs.service
fp6-vendor-blobs.preset
"
package() {
install -Dm755 "$srcdir"/fp6-vendor-blobs-extract \
"$pkgdir"/usr/lib/fp6-vendor-blobs/extract
install -Dm644 "$srcdir"/fp6-vendor-blobs.service \
"$pkgdir"/usr/lib/systemd/system/fp6-vendor-blobs.service
# enabled unconditionally: the unit is a fast no-op once every manifest
# dest exists, and blobs appearing on first boot must not depend on a
# manual systemctl enable. sysinit = the real (pre-coldplug) run;
# multi-user = the post-udev retry if the early run failed (see unit)
mkdir -p "$pkgdir"/etc/systemd/system/sysinit.target.wants \
"$pkgdir"/etc/systemd/system/multi-user.target.wants
ln -s /usr/lib/systemd/system/fp6-vendor-blobs.service \
"$pkgdir"/etc/systemd/system/sysinit.target.wants/fp6-vendor-blobs.service
ln -s /usr/lib/systemd/system/fp6-vendor-blobs.service \
"$pkgdir"/etc/systemd/system/multi-user.target.wants/fp6-vendor-blobs.service
# ...and a preset, because the symlink alone does NOT survive: image
# build runs `systemctl preset-all`, which removes .wants links for any
# unit not enabled by a preset. That is what shipped the 2026-08-24
# image with the service `disabled; preset: disabled` -- no blob
# extracted, no sound card. See journal/blobs/ 2026-08-28.
install -Dm644 "$srcdir"/fp6-vendor-blobs.preset \
"$pkgdir"/usr/lib/systemd/system-preset/50-fp6-vendor-blobs.preset
mkdir -p "$pkgdir"/usr/share/fp6-vendor-blobs/manifest.d
}
sha512sums="
a71b2c86f980734d0aae6e135b26272fe52ae5603050bea52f55f7e74c8bd98c62b6194047711248d4fef40851792adc47d77c40016d99a0d68ecd2459894b80 fp6-vendor-blobs-extract
b4c290095d9f39515378dfef08de720ce49324210342aa13c131dfce1103785e796e6f821f0c659671a4c44b46f466ce0e03f11f216fdcdee2a99db5e7970800 fp6-vendor-blobs.service
9e79dd0aed13f11a71282aa24b2a26331e85c105e25ab0c0fed6189b8c300769a5f4308b18b91d9855868d658ad3a57c03e26c9b11bd27fd5e03f9a5decbbd6a fp6-vendor-blobs.preset
"