aports: extract aw88261_acf.bin on-device instead of shipping it
New package fp6-vendor-blobs: a manifest-driven systemd oneshot that
copies proprietary blobs out of the stock Android partitions on first
boot. pmOS installs flash only boot+userdata, so every installed unit
still carries the stock vendor/dsp partitions - the device duplicates a
file it already contains, for its own operation, and nothing proprietary
is distributed by us. Partitions are mounted read-only (ext4 additionally
with noload - not even a journal replay touches the stock data), every
copy is sha256-pinned and a miss fails loudly, and the consuming devices
are unbound and re-probed afterwards so the feature works the same boot.
The rebind is unconditional by design: aw88261 binds on a bare i2c
chip-id probe and requests the ACF only at ASoC card init (~21 s, after
SoundWire enumeration), so a bound device can still be one that lost the
firmware race - and that failed request is never retried.
soc-fairphone-fp6-audio (pkgver 4) stops shipping the blob, installs the
manifest fragment instead, and re-runs the extractor from
post-install/post-upgrade so upgrades restore the file immediately (the
old package version removed it on upgrade). License drops back to plain
BSD-3-Clause - nothing proprietary left in the package.
Verified on the dev phone (fp6 repo journal/blobs/captures/
2026-08-24-first-boot-extractor-verification.txt): first-boot extraction
+ same-boot audio, mid-session post-upgrade recovery, and the everyday
fast-path no-op; committed files byte-identical to the tested deployment.
Assisted-by: Claude:claude-fable-5
2026-08-24 21:00:34 +02:00
|
|
|
# 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
|
aports: extract vendor blobs before udev coldplug so first-boot audio fully works
The preset fix (6ecc1dc) makes the unit run, but multi-user is too late: the
sound card probes at ~21 s, hard-fails (-2, no retry) on the missing ACF, and
the extractor's amp rebind at ~60 s cannot re-form a card whose machine
driver already failed. Re-probing the machine driver does re-form it, but a
late-formed card has a dead capture path - the wcd9378 TX sequencer refuses
PS0 (act_ps 0x3) until the next boot. So rebinding after the fact can never
fully win; extraction has to happen before the drivers probe.
- fp6-vendor-blobs.service: DefaultDependencies=no, run after remount-fs and
before systemd-udev-trigger, so blobs exist before module coldplug.
multi-user stays a second Wants as a post-udev retry if the early run
failed (by-partlabel/make-dynpart-mappings fallbacks need udev).
- aw88261-acf.manifest: add 'rebind platform sound' so the fallback path at
least recovers playback the same boot (capture then heals on reboot).
- fp6-vendor-blobs.post-upgrade (pkgrel 1): systemctl preset + immediate
extract, so installs of the 2026-08-24 image (unit shipped disabled, no
version bump to deliver the preset) finally heal via plain apk upgrade.
- soc-fairphone-fp6-audio pkgrel 1: carries the manifest change.
Verified on the dev phone with the exact staged bytes (sha256-compared):
simulated fresh install (ACF removed, reboot) extracts at 13.3 s, coldplug
probes the amps at 15.1 s, card init at 20.9 s loads the ACF cleanly, and a
1 kHz speaker-to-mic loopback passes on that same first boot with zero TX
sequencer warnings; next boot takes the all-dests-present fast path in 25 ms.
Evidence: fp6 repo journal/blobs/, 2026-08-29.
Assisted-by: Claude:claude-fable-5
2026-08-29 21:53:02 +02:00
|
|
|
pkgrel=1
|
aports: extract aw88261_acf.bin on-device instead of shipping it
New package fp6-vendor-blobs: a manifest-driven systemd oneshot that
copies proprietary blobs out of the stock Android partitions on first
boot. pmOS installs flash only boot+userdata, so every installed unit
still carries the stock vendor/dsp partitions - the device duplicates a
file it already contains, for its own operation, and nothing proprietary
is distributed by us. Partitions are mounted read-only (ext4 additionally
with noload - not even a journal replay touches the stock data), every
copy is sha256-pinned and a miss fails loudly, and the consuming devices
are unbound and re-probed afterwards so the feature works the same boot.
The rebind is unconditional by design: aw88261 binds on a bare i2c
chip-id probe and requests the ACF only at ASoC card init (~21 s, after
SoundWire enumeration), so a bound device can still be one that lost the
firmware race - and that failed request is never retried.
soc-fairphone-fp6-audio (pkgver 4) stops shipping the blob, installs the
manifest fragment instead, and re-runs the extractor from
post-install/post-upgrade so upgrades restore the file immediately (the
old package version removed it on upgrade). License drops back to plain
BSD-3-Clause - nothing proprietary left in the package.
Verified on the dev phone (fp6 repo journal/blobs/captures/
2026-08-24-first-boot-extractor-verification.txt): first-boot extraction
+ same-boot audio, mid-session post-upgrade recovery, and the everyday
fast-path no-op; committed files byte-identical to the tested deployment.
Assisted-by: Claude:claude-fable-5
2026-08-24 21:00:34 +02:00
|
|
|
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"
|
aports: extract vendor blobs before udev coldplug so first-boot audio fully works
The preset fix (6ecc1dc) makes the unit run, but multi-user is too late: the
sound card probes at ~21 s, hard-fails (-2, no retry) on the missing ACF, and
the extractor's amp rebind at ~60 s cannot re-form a card whose machine
driver already failed. Re-probing the machine driver does re-form it, but a
late-formed card has a dead capture path - the wcd9378 TX sequencer refuses
PS0 (act_ps 0x3) until the next boot. So rebinding after the fact can never
fully win; extraction has to happen before the drivers probe.
- fp6-vendor-blobs.service: DefaultDependencies=no, run after remount-fs and
before systemd-udev-trigger, so blobs exist before module coldplug.
multi-user stays a second Wants as a post-udev retry if the early run
failed (by-partlabel/make-dynpart-mappings fallbacks need udev).
- aw88261-acf.manifest: add 'rebind platform sound' so the fallback path at
least recovers playback the same boot (capture then heals on reboot).
- fp6-vendor-blobs.post-upgrade (pkgrel 1): systemctl preset + immediate
extract, so installs of the 2026-08-24 image (unit shipped disabled, no
version bump to deliver the preset) finally heal via plain apk upgrade.
- soc-fairphone-fp6-audio pkgrel 1: carries the manifest change.
Verified on the dev phone with the exact staged bytes (sha256-compared):
simulated fresh install (ACF removed, reboot) extracts at 13.3 s, coldplug
probes the amps at 15.1 s, card init at 20.9 s loads the ACF cleanly, and a
1 kHz speaker-to-mic loopback passes on that same first boot with zero TX
sequencer warnings; next boot takes the all-dests-present fast path in 25 ms.
Evidence: fp6 repo journal/blobs/, 2026-08-29.
Assisted-by: Claude:claude-fable-5
2026-08-29 21:53:02 +02:00
|
|
|
install="$pkgname.post-upgrade"
|
aports: extract aw88261_acf.bin on-device instead of shipping it
New package fp6-vendor-blobs: a manifest-driven systemd oneshot that
copies proprietary blobs out of the stock Android partitions on first
boot. pmOS installs flash only boot+userdata, so every installed unit
still carries the stock vendor/dsp partitions - the device duplicates a
file it already contains, for its own operation, and nothing proprietary
is distributed by us. Partitions are mounted read-only (ext4 additionally
with noload - not even a journal replay touches the stock data), every
copy is sha256-pinned and a miss fails loudly, and the consuming devices
are unbound and re-probed afterwards so the feature works the same boot.
The rebind is unconditional by design: aw88261 binds on a bare i2c
chip-id probe and requests the ACF only at ASoC card init (~21 s, after
SoundWire enumeration), so a bound device can still be one that lost the
firmware race - and that failed request is never retried.
soc-fairphone-fp6-audio (pkgver 4) stops shipping the blob, installs the
manifest fragment instead, and re-runs the extractor from
post-install/post-upgrade so upgrades restore the file immediately (the
old package version removed it on upgrade). License drops back to plain
BSD-3-Clause - nothing proprietary left in the package.
Verified on the dev phone (fp6 repo journal/blobs/captures/
2026-08-24-first-boot-extractor-verification.txt): first-boot extraction
+ same-boot audio, mid-session post-upgrade recovery, and the everyday
fast-path no-op; committed files byte-identical to the tested deployment.
Assisted-by: Claude:claude-fable-5
2026-08-24 21:00:34 +02:00
|
|
|
options="!check"
|
|
|
|
|
source="
|
|
|
|
|
fp6-vendor-blobs-extract
|
|
|
|
|
fp6-vendor-blobs.service
|
2026-09-15 22:36:12 +02:00
|
|
|
fp6-vendor-blobs.preset
|
aports: extract aw88261_acf.bin on-device instead of shipping it
New package fp6-vendor-blobs: a manifest-driven systemd oneshot that
copies proprietary blobs out of the stock Android partitions on first
boot. pmOS installs flash only boot+userdata, so every installed unit
still carries the stock vendor/dsp partitions - the device duplicates a
file it already contains, for its own operation, and nothing proprietary
is distributed by us. Partitions are mounted read-only (ext4 additionally
with noload - not even a journal replay touches the stock data), every
copy is sha256-pinned and a miss fails loudly, and the consuming devices
are unbound and re-probed afterwards so the feature works the same boot.
The rebind is unconditional by design: aw88261 binds on a bare i2c
chip-id probe and requests the ACF only at ASoC card init (~21 s, after
SoundWire enumeration), so a bound device can still be one that lost the
firmware race - and that failed request is never retried.
soc-fairphone-fp6-audio (pkgver 4) stops shipping the blob, installs the
manifest fragment instead, and re-runs the extractor from
post-install/post-upgrade so upgrades restore the file immediately (the
old package version removed it on upgrade). License drops back to plain
BSD-3-Clause - nothing proprietary left in the package.
Verified on the dev phone (fp6 repo journal/blobs/captures/
2026-08-24-first-boot-extractor-verification.txt): first-boot extraction
+ same-boot audio, mid-session post-upgrade recovery, and the everyday
fast-path no-op; committed files byte-identical to the tested deployment.
Assisted-by: Claude:claude-fable-5
2026-08-24 21:00:34 +02:00
|
|
|
"
|
|
|
|
|
|
|
|
|
|
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
|
aports: extract vendor blobs before udev coldplug so first-boot audio fully works
The preset fix (6ecc1dc) makes the unit run, but multi-user is too late: the
sound card probes at ~21 s, hard-fails (-2, no retry) on the missing ACF, and
the extractor's amp rebind at ~60 s cannot re-form a card whose machine
driver already failed. Re-probing the machine driver does re-form it, but a
late-formed card has a dead capture path - the wcd9378 TX sequencer refuses
PS0 (act_ps 0x3) until the next boot. So rebinding after the fact can never
fully win; extraction has to happen before the drivers probe.
- fp6-vendor-blobs.service: DefaultDependencies=no, run after remount-fs and
before systemd-udev-trigger, so blobs exist before module coldplug.
multi-user stays a second Wants as a post-udev retry if the early run
failed (by-partlabel/make-dynpart-mappings fallbacks need udev).
- aw88261-acf.manifest: add 'rebind platform sound' so the fallback path at
least recovers playback the same boot (capture then heals on reboot).
- fp6-vendor-blobs.post-upgrade (pkgrel 1): systemctl preset + immediate
extract, so installs of the 2026-08-24 image (unit shipped disabled, no
version bump to deliver the preset) finally heal via plain apk upgrade.
- soc-fairphone-fp6-audio pkgrel 1: carries the manifest change.
Verified on the dev phone with the exact staged bytes (sha256-compared):
simulated fresh install (ACF removed, reboot) extracts at 13.3 s, coldplug
probes the amps at 15.1 s, card init at 20.9 s loads the ACF cleanly, and a
1 kHz speaker-to-mic loopback passes on that same first boot with zero TX
sequencer warnings; next boot takes the all-dests-present fast path in 25 ms.
Evidence: fp6 repo journal/blobs/, 2026-08-29.
Assisted-by: Claude:claude-fable-5
2026-08-29 21:53:02 +02:00
|
|
|
# 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
|
aports: extract aw88261_acf.bin on-device instead of shipping it
New package fp6-vendor-blobs: a manifest-driven systemd oneshot that
copies proprietary blobs out of the stock Android partitions on first
boot. pmOS installs flash only boot+userdata, so every installed unit
still carries the stock vendor/dsp partitions - the device duplicates a
file it already contains, for its own operation, and nothing proprietary
is distributed by us. Partitions are mounted read-only (ext4 additionally
with noload - not even a journal replay touches the stock data), every
copy is sha256-pinned and a miss fails loudly, and the consuming devices
are unbound and re-probed afterwards so the feature works the same boot.
The rebind is unconditional by design: aw88261 binds on a bare i2c
chip-id probe and requests the ACF only at ASoC card init (~21 s, after
SoundWire enumeration), so a bound device can still be one that lost the
firmware race - and that failed request is never retried.
soc-fairphone-fp6-audio (pkgver 4) stops shipping the blob, installs the
manifest fragment instead, and re-runs the extractor from
post-install/post-upgrade so upgrades restore the file immediately (the
old package version removed it on upgrade). License drops back to plain
BSD-3-Clause - nothing proprietary left in the package.
Verified on the dev phone (fp6 repo journal/blobs/captures/
2026-08-24-first-boot-extractor-verification.txt): first-boot extraction
+ same-boot audio, mid-session post-upgrade recovery, and the everyday
fast-path no-op; committed files byte-identical to the tested deployment.
Assisted-by: Claude:claude-fable-5
2026-08-24 21:00:34 +02:00
|
|
|
ln -s /usr/lib/systemd/system/fp6-vendor-blobs.service \
|
|
|
|
|
"$pkgdir"/etc/systemd/system/multi-user.target.wants/fp6-vendor-blobs.service
|
2026-09-15 22:36:12 +02:00
|
|
|
# ...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
|
aports: extract aw88261_acf.bin on-device instead of shipping it
New package fp6-vendor-blobs: a manifest-driven systemd oneshot that
copies proprietary blobs out of the stock Android partitions on first
boot. pmOS installs flash only boot+userdata, so every installed unit
still carries the stock vendor/dsp partitions - the device duplicates a
file it already contains, for its own operation, and nothing proprietary
is distributed by us. Partitions are mounted read-only (ext4 additionally
with noload - not even a journal replay touches the stock data), every
copy is sha256-pinned and a miss fails loudly, and the consuming devices
are unbound and re-probed afterwards so the feature works the same boot.
The rebind is unconditional by design: aw88261 binds on a bare i2c
chip-id probe and requests the ACF only at ASoC card init (~21 s, after
SoundWire enumeration), so a bound device can still be one that lost the
firmware race - and that failed request is never retried.
soc-fairphone-fp6-audio (pkgver 4) stops shipping the blob, installs the
manifest fragment instead, and re-runs the extractor from
post-install/post-upgrade so upgrades restore the file immediately (the
old package version removed it on upgrade). License drops back to plain
BSD-3-Clause - nothing proprietary left in the package.
Verified on the dev phone (fp6 repo journal/blobs/captures/
2026-08-24-first-boot-extractor-verification.txt): first-boot extraction
+ same-boot audio, mid-session post-upgrade recovery, and the everyday
fast-path no-op; committed files byte-identical to the tested deployment.
Assisted-by: Claude:claude-fable-5
2026-08-24 21:00:34 +02:00
|
|
|
mkdir -p "$pkgdir"/usr/share/fp6-vendor-blobs/manifest.d
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sha512sums="
|
|
|
|
|
a71b2c86f980734d0aae6e135b26272fe52ae5603050bea52f55f7e74c8bd98c62b6194047711248d4fef40851792adc47d77c40016d99a0d68ecd2459894b80 fp6-vendor-blobs-extract
|
aports: extract vendor blobs before udev coldplug so first-boot audio fully works
The preset fix (6ecc1dc) makes the unit run, but multi-user is too late: the
sound card probes at ~21 s, hard-fails (-2, no retry) on the missing ACF, and
the extractor's amp rebind at ~60 s cannot re-form a card whose machine
driver already failed. Re-probing the machine driver does re-form it, but a
late-formed card has a dead capture path - the wcd9378 TX sequencer refuses
PS0 (act_ps 0x3) until the next boot. So rebinding after the fact can never
fully win; extraction has to happen before the drivers probe.
- fp6-vendor-blobs.service: DefaultDependencies=no, run after remount-fs and
before systemd-udev-trigger, so blobs exist before module coldplug.
multi-user stays a second Wants as a post-udev retry if the early run
failed (by-partlabel/make-dynpart-mappings fallbacks need udev).
- aw88261-acf.manifest: add 'rebind platform sound' so the fallback path at
least recovers playback the same boot (capture then heals on reboot).
- fp6-vendor-blobs.post-upgrade (pkgrel 1): systemctl preset + immediate
extract, so installs of the 2026-08-24 image (unit shipped disabled, no
version bump to deliver the preset) finally heal via plain apk upgrade.
- soc-fairphone-fp6-audio pkgrel 1: carries the manifest change.
Verified on the dev phone with the exact staged bytes (sha256-compared):
simulated fresh install (ACF removed, reboot) extracts at 13.3 s, coldplug
probes the amps at 15.1 s, card init at 20.9 s loads the ACF cleanly, and a
1 kHz speaker-to-mic loopback passes on that same first boot with zero TX
sequencer warnings; next boot takes the all-dests-present fast path in 25 ms.
Evidence: fp6 repo journal/blobs/, 2026-08-29.
Assisted-by: Claude:claude-fable-5
2026-08-29 21:53:02 +02:00
|
|
|
b4c290095d9f39515378dfef08de720ce49324210342aa13c131dfce1103785e796e6f821f0c659671a4c44b46f466ce0e03f11f216fdcdee2a99db5e7970800 fp6-vendor-blobs.service
|
2026-09-15 22:36:12 +02:00
|
|
|
9e79dd0aed13f11a71282aa24b2a26331e85c105e25ab0c0fed6189b8c300769a5f4308b18b91d9855868d658ad3a57c03e26c9b11bd27fd5e03f9a5decbbd6a fp6-vendor-blobs.preset
|
aports: extract aw88261_acf.bin on-device instead of shipping it
New package fp6-vendor-blobs: a manifest-driven systemd oneshot that
copies proprietary blobs out of the stock Android partitions on first
boot. pmOS installs flash only boot+userdata, so every installed unit
still carries the stock vendor/dsp partitions - the device duplicates a
file it already contains, for its own operation, and nothing proprietary
is distributed by us. Partitions are mounted read-only (ext4 additionally
with noload - not even a journal replay touches the stock data), every
copy is sha256-pinned and a miss fails loudly, and the consuming devices
are unbound and re-probed afterwards so the feature works the same boot.
The rebind is unconditional by design: aw88261 binds on a bare i2c
chip-id probe and requests the ACF only at ASoC card init (~21 s, after
SoundWire enumeration), so a bound device can still be one that lost the
firmware race - and that failed request is never retried.
soc-fairphone-fp6-audio (pkgver 4) stops shipping the blob, installs the
manifest fragment instead, and re-runs the extractor from
post-install/post-upgrade so upgrades restore the file immediately (the
old package version removed it on upgrade). License drops back to plain
BSD-3-Clause - nothing proprietary left in the package.
Verified on the dev phone (fp6 repo journal/blobs/captures/
2026-08-24-first-boot-extractor-verification.txt): first-boot extraction
+ same-boot audio, mid-session post-upgrade recovery, and the everyday
fast-path no-op; committed files byte-identical to the tested deployment.
Assisted-by: Claude:claude-fable-5
2026-08-24 21:00:34 +02:00
|
|
|
"
|