Releases: petronijus/nexusQ-reloaded
Release list
v1.6.3 — companion app + LAN control bridge
Highlights
📱 A companion app + an on-device control bridge — a phone/desktop remote for the
Q (volume, LED theme + brightness, now-playing), replacing the dead 2012 Google
companion app.
nexusq-control — a new LAN control bridge (pure-Python, TCP 45015, mDNS
_nexusq._tcp, line-delimited JSON). It fans out to: the ALSA softvol
(volume/mute), nexusqd over its Unix socket (LED theme + brightness), and a
librespot --onevent hook (now-playing). Protocol: companion/PROTOCOL.md.
Software master volume — a nexusq_soft softvol control (NexusQ) layered on
the v1.6.2 audio tee, shared by librespot (--mixer alsa --alsa-mixer-control NexusQ)
and the companion, so Spotify-Connect volume and companion volume are one knob —
and the LED visualizer still tracks the (post-volume) output.
nexusqd brightness <0-255> — a software ring-brightness scalar (no firmware change).
Companion app (companion/app) — a cross-platform Flutter remote (sphere UI,
animated LED ring, mDNS auto-discovery; volume + LED theme/brightness + now-playing).
Built and installed separately on the phone — not part of the device image.
Verified live on a clean flash: the bridge auto-starts (active), answers every
protocol method, volume works, the LED visualizer still reacts to playback, and mDNS
advertises "Nexus Q". (Getting the bridge to auto-start was a saga — see
docs/2026-07-01-companion-bridge-boot-enablement.md: a systemd-preset to survive
preset-all, and dropping an After= that formed a boot ordering cycle.)
The kernel is unchanged from v1.6.1/v1.6.2 —
nexusq-boot-v1.6.3.imgis
byte-identical to v1.6.2's. Only the rootfs changed, so if v1.6.2's boot is
already on the device you only need to flashuserdata.
Known issues
- Transport (play/pause/next) is
unavailablein v1 — librespot is a
Spotify-Connect receiver with no local transport API; transport happens from the
Spotify app. The protocol reserves the slot for a future backend.
Install
zstd -d nexusq-rootfs-v1.6.3-sparse.img.zst
fastboot flash boot nexusq-boot-v1.6.3.img # optional if v1.6.2 boot is already flashed
fastboot -S 100M flash userdata nexusq-rootfs-v1.6.3-sparse.imgWiFi is per-device (a flash wipes it). Once on WiFi, the companion app auto-discovers
the device via mDNS; the Spotify "Nexus Q" target appears on the same network.
Assets
nexusq-boot-v1.6.3.img(5.0 MiB) — kernel + appended SMP DTB; identical to v1.6.2nexusq-rootfs-v1.6.3-sparse.img.zst(447 MiB; ~2.08 GiB raw) — zstd all-RAW sparsenexusq-v1.6.3.sha256— checksums
v1.6.2 — LED music visualizer reacts to playback
Highlights
🔴🎵 The LED ring now reacts to the music. v1.6.1 routed librespot straight to
the speaker, so nexusqd's audio analyzer (the snd-aloop loopback) got nothing and
the ring stayed idle during playback. The nexusq ALSA PCM is now a tee
(type multi + type route) that duplicates the 48 kHz stereo to BOTH the TAS5713
speaker AND the snd-aloop loopback (hw:Loopback,0); nexusqd's existing arecord
tap on hw:Loopback,1 drives the FFT/beat visualizer while the speaker plays. The
speaker is the timing master; the loopback slave is plughw, so it adapts to
whatever rate the cable is at (nexusqd's arecord may have set it) and never blocks
playback. New /etc/modules-load.d/snd-aloop.conf auto-loads the loopback
(CONFIG_SND_ALOOP=m). device-google-steelhead pkgrel 12.
Verified live: the ring pulses/animates to Spotify; no ALSA/xrun errors,
nexusqd/librespot NRestarts=0; the tee opens regardless of which side grabs the
loopback first.
The kernel is unchanged from v1.6.1 (same TAS5713 2× audio fix) —
nexusq-boot-v1.6.2.imgis byte-identical to v1.6.1's. Only the rootfs
changed, so if v1.6.1's boot is already on the device you only need to flash
userdata.
Install
zstd -d nexusq-rootfs-v1.6.2-sparse.img.zst
fastboot flash boot nexusq-boot-v1.6.2.img # optional if v1.6.1 boot is already flashed
fastboot -S 100M flash userdata nexusq-rootfs-v1.6.2-sparse.imgWiFi is configured per-device (a flash wipes it); the Spotify "Nexus Q" target
appears on a phone on the same WiFi.
Known issues
- The Spotify Connect session can briefly go "inactive" on the first play and
reconnect (librespot "context is not available" — a single-track-vs-playlist
quirk; no ALSA error). Playback is stable afterwards.
Assets
nexusq-boot-v1.6.2.img(5.0 MiB) — kernel + appended SMP DTB; identical to v1.6.1nexusq-rootfs-v1.6.2-sparse.img.zst(448 MiB; ~2.08 GiB raw) — zstd all-RAW sparsenexusq-v1.6.2.sha256— checksums
v1.6.1 — TAS5713 audio fixed (2× speed bug) + Spotify Connect baked in
Highlights
🔊 TAS5713 speaker audio fixed — it played exactly 2× too fast. Root cause:
simple-audio-card drove the McBSP2→TAS5713 I2S link as bit/frame master but never
set the McBSP bit-clock divider, so omap-mcbsp left CLKGDV = 0 (the undivided
24.576 MHz functional clock as BCLK) and sized the frame as in_freq/rate = 256
BCLK → FSYNC = 96 kHz for a 48 kHz stream = 2× too fast. Kernel patch 0022
derives CLKGDV from the real func-clock rate and uses a minimal wlen*channels
I2S frame → CLKGDV 15, BCLK 1.536 MHz, FSYNC 48 kHz, bit-identical to the factory
kernel. Verified on hardware: 60 s of audio now plays in 60.00 s (was ~30 s).
This 2× is also why librespot auto-skipped tracks ~40 s in. (The "B7 MCLK 16 vs
12.288 MHz" theory was a red herring — mainline tas571x has no .set_sysclk.)
🎵 Spotify Connect (librespot) baked into the build. The image now ships
librespot — advertising as "Nexus Q" — with an enabled systemd unit, an ALSA
nexusq PCM that resamples to the device's clean 48 kHz and addresses the speaker
by name (hw:CARD=NexusQSpeaker,0 — card numbers race TAS5713/HDMI across
boots), and an nftables drop-in opening mDNS + the zeroconf port. Discovery + auth
- streaming verified over 5 GHz WiFi, audio at correct pitch.
🛠 Build fixes (docker-build.sh): the fakeroot-as-root patch re-targeted for
pmbootstrap 3.10.1 (env-dict format changed → patch was silently skipped → fakeroot
hang); firmware-google-steelhead now built explicitly so cold builds don't fail
at install.
Verified end-to-end from a clean flash: uname #26-postmarketOS, python3 -S
rc 0, audio 60.00 s, librespot advertising, WiFi, dual-core SMP @ 1.2 GHz.
Install
See INSTALL.md. Decompress the rootfs first, then flash:
zstd -d nexusq-rootfs-v1.6.1-sparse.img.zst
fastboot flash boot nexusq-boot-v1.6.1.img
fastboot -S 100M flash userdata nexusq-rootfs-v1.6.1-sparse.imgAfter first boot the Spotify "Nexus Q" target appears on your phone (same WiFi);
WiFi is configured per-device (a flash wipes it).
Assets
nexusq-boot-v1.6.1.img(5.0 MiB) — kernel + appended SMP DTB, ramdisk-lessnexusq-rootfs-v1.6.1-sparse.img.zst(447 MiB; ~2.08 GiB raw) — zstd-compressed
all-RAW Android-sparse rootfs (byte-exact on the non-erased eMMC)nexusq-v1.6.1.sha256— checksums
v1.6.0 — working python3 on the device
First release with a working python3 on the device, hardware-verified from a
clean flash. Over 1.5.0: a working armv7 python3 — the actual fix was the
raw2simg.py byte-exact (all-RAW) flash; the on-device SIGSEGV was a flash bug, not
a build bug (a local python3 rebuild supersedes Alpine's broken -r2, with a
build-integrity gate + ship gate kept as a safety net) — plus zram compressed swap,
user namespaces, on-device gdb/python3-dbg, and a live re-confirmation of
dual-core SMP + cpufreq-to-1.2 GHz power/thermal.
Added
- zram compressed swap. Kernel
CONFIG_ZRAM=mplus
deviceinfo_zram_swap_algo="lzo-rle"brings uppostmarketos-zram-swap. The
mainline ZRAM module here only carries the lzo/lzo-rle backend, so the service's
default zstd failed (zramctl: failed to set algorithm: Invalid argument)
and swap never came up; lzo-rle is also the CPU-cheap pick for this Cortex-A9.
Verified live:/dev/zram0lzo-rle, 1.4 G, active[SWAP]. (linux APKBUILD
pkgrel 23→24.) - User namespaces —
CONFIG_USER_NS=y. Verified live:
max_user_namespaces=7716,unshare --userworks. - Dual-core SMP re-confirmed on the full-rootfs image —
nproc=2,
cpu/online=0-1, both Cortex-A9 in/proc/cpuinfo. (SMP shipped in 1.2.0; this
corrects any stale "CPU1 not brought up / SMP is groundwork" framing — it is done
and working on the current image.) - CPU power/thermal health confirmed live — scales 350/700/920/1200 MHz,
reaches 1.2 GHz under load, VDD_MPU tracks the OPP exactly (1200→1380, 920→1317,
350→1025 mV; abb_mpu FBB@Nitro 1375 mV). Idle ~70 °C, peak 95 °C under sustained
2-core load (no throttle; 100 °C passive trip not reached).
Changed
- Build infra: local
python3override aport + gated Phase 7d.
docker-build.shstagespmos/python3/→main/python3(Phase 6) and builds it
(pmbootstrap --no-cross build python3 --arch armv7, Phase 7d) so a higher pkgrel
(now r5) supersedes Alpine's brokenpython3-3.14.5-r2in the rootfs. The override
drops--with-lto+--enable-optimizationsand the!gettext-devmakedepends
token (pmbootstrap's apk wrapper rejects!entries), keeps stock-O2and the
default linker (bfd). Phase 7d gates every built libpython with
scripts/verify-libpython-clean.pyand rebuilds on residual corruption (pkgrel-exact
apk selection, no stale-apk glob); Phase 10 re-gates the installed rootfs libpython
before emitting an image — a build-integrity safety net (the on-device crash was a
flash bug, see Fixed; this only guarantees the build feeding the flash is clean). device-google-steelheadno longer maskssleep-inhibitor.service; adds
on-device debug tools. The/dev/nullmask was removed in favour of fixing the
root cause (the python crash, now fixed below); the image also shipsgdb(16.3) +
python3-dbg(used to coredump-debug the crash on hardware; gdb linkslibpython,
so it works once python links a clean libpython). (device APKBUILD pkgrel 6→10.)
Fixed
- Flash: the rootfs sparse image is now byte-exact (all-RAW, no
DONT_CARE).
raw2simg.py(raw ext4 → Android sparse for the 2012 U-Boot fastboot, which lacks
FILL-chunk support) used to emit every all-zero 4 KiB block as aDONT_CAREchunk to
shrink the image — but fastboot skipsDONT_CAREblocks, which is only correct
on a pre-erased partition. The Nexus Q's U-Boot does not eraseuserdata, so
each skipped block kept STALE data from the previous flash, re-corrupting on-device
file zero-regions — specifically libpython's.PyRuntime/.data.rel.ro(PROGBITS,
read duringPy_Initialize) — which was the actual and only root cause of the
on-device armv7 python SIGSEGV (rc 139), even though the flashed (and built) image
was provably clean. Forensic signature distinguishing flash- from build-corruption:
the on-device libpython differed from the (gate-CLEAN) flashed image in exactly 47
4 KiB blocks, all "image-zero → device-garbage", 0 other
(.PyRuntime longest_run 30652); the image gated CLEAN, the device gated CORRUPT, and
scp-ing the clean image libpython over the device's →python3 -S -c ''rc 0
instantly — proof it was the flash, not the build. Fix:raw2simg.pynow encodes
every block as RAW (noDONT_CARE), so the flash is byte-exact regardless of prior
eMMC content (sparse ≈ raw size; correctness over compression). Verified by a de-sparse
round-trip (md5 of de-sparsed == raw image) and on hardware: a fresh flash (no
live-patch) of a default-linker (bfd) build gives/usr/lib/libpython3.14.so.1.0md5
79a0d4ace1358bb2d94c8a4d72479da9,SYSPY_OK 3.14.5 … [GCC 15.2.0],SYS_PY_RC=0.
Lesson: integrity-verify what the device runs, not just the built artifact. See
docs/2026-06-28-session-findings.md. - armv7
python3works on the device — the on-device SIGSEGV was the FLASH bug
above, not a build bug. Alpine'spython3-3.14.5-r2SIGSEGVed deterministically on
the Cortex-A9 (python3 -S -c ''→ rc 139 duringPy_Initialize), taking down
onboard,blueman-applet,sleep-inhibitor.serviceandgdb(it links
libpython). The single root cause was theraw2simg.pyDONT_CAREflash bug
(above): a re-flash over non-erased eMMC left stale garbage in libpython's
should-be-zero.PyRuntime/.data.rel.ro, landing on
interp->types.builtins.num_initialized(read back as0xf0012b00) → wild
type-index deref → SIGSEGV. v1.6.0 ships a localpmos/python3/override (same 3.14.5
at a higher pkgrel, r5, default linker / bfd) so it supersedes Alpine's-r2;
the override drops--with-lto+--enable-optimizationsand the!gettext-dev
makedepends token, keeps stock-O2. A qemu-user "linker mmap zero-fill corrupts
the build" theory and a gold-linker workaround (-fuse-ld=gold -Wl,--no-mmap-output-file,binutils-goldmakedep) were investigated and DROPPED as
unnecessary — the build was never reproducibly corrupt: 6 independent default-linker
builds were all integrity-gate-clean, and a bfd build (gold-note absent, libpython md5
79a0d4ace1358bb2d94c8a4d72479da9), flashed via the corrected all-RAWraw2simg, ran
python3 -S -c ''rc 0 on the real device (6/6 clean would be ~1.6 % if a real 50 %
build coin-flip existed). Retained — not as a "gold fix" but as a cheap
build-integrity safety net that catches zero-region corruption from any source:
scripts/verify-libpython-clean.py(flags long non-zero runs in those zero-regions;
clean ≤52 B, corrupt ≥22000 B, threshold 256), run in a Phase-7d gate+retry loop and
again as a Phase-10 ship gate, with pkgrel-exact apk selection. Other early suspects
also disproven: LTO/PGO, LDREXD alignment, gnu2/TLSDESC, optimization level. The
all-RAW flash fix above is what actually fixed the device; the gate only guarantees the
build feeding it is clean. Seedocs/2026-06-28-session-findings.md. - Build-pipeline: rootfs python ≠ the verified apk — fixed. Phase 7d's old bare
python3-3.14.5-r*.apkglob could match a stale apk in the persistent work-volume
repo rather than the one just built, so the rootfs could install a different build than
the one gated. Fixed by selecting the exactpkgver-pkgrelapk, gating that file,
and re-gating the installed rootfs libpython at ship time (the version-only check
that green-lit a mismatch is gone). (The apparent "two r4 builds, one crashes / one
runs" that first surfaced this was almost certainly a post-flash device pull — the
flash bug above — misread as build corruption, not a real build coin-flip.)
Known issues / in progress
- On-board LAN9500A Ethernet still down — the v1.4.0 cpufreq boot-timing
regression is unchanged:smsc95xxregisters but the device never enumerates, no
eth0. Use WiFi / the USB gadget. (Fix tracked for 1.4.1.)
Full Changelog: v1.5.0...v1.6.0
v1.5.0
[1.5.0] - 2026-06-26
Added
- NFC: the PN544 stack is built into the kernel (NFC / HCI / PN544 / PN544_I2C
=y) with stock-faithful tweaks — a 20 ms VEN settle and a level-triggered IRQ.
The chip is proven alive (it ACKs i2c when powered); full NFC functionality is a
follow-up. - Nexus Q diagnostics suite.
nq-healthdcontinuously watches the things that
silently fail in the field (LED-ring / nexusqd hangs, VDD_MPU-vs-OPP drift,
thermal throttle, kernel errors) and logs to/var/log/nq-health;
nq-diag-snapshotcaptures a full one-shot device snapshot. Both ship enabled in
the device image, with host-side helpers (scripts/diag/) and anexusq-diag
skill to collect and analyse it over the best available link. - nexusqd now signals systemd readiness + watchdog via
sd_notify
(self-contained, no libsystemd dependency), so the LED-ring daemon runs as a
properType=notifyunit.
Changed
- DTS regulators now point at the real board rails — DSS
vdda_video→vcxio,
tmp101vs→v1v8, the Bluetoothvbat/vddio, and the TAS5713 ampAVDD/DVDD→a
3V3 rail replace placeholder dummies. The spurious "supplying voltage" warnings
drop from 10 to 5. - Default cpufreq governor →
conservative— idle now settles at 350 MHz (vs
ondemand's 920 MHz), ~66 °C, instead of holding a high clock. - Ethernet (LAN9500A) is reliable again — it came up on every boot tested in
v1.5.0 (the v1.4.0 cpufreq-build bring-up intermittency was not reproducible),
sustaining full ~100 Mbit/s line-rate throughput. - Device image UI: added
nm-tray(network applet),blueman(Bluetooth
manager) andbreeze-iconsto the LXQt-Wayland session.
Fixed
- WiFi: the BCM4330 radio no longer sleeps when idle. brcmfmac forced the
firmwarempc(Minimum Power Consumption) iovar on, powering the radio down
between packets — ~30 % packet loss and 270–530 ms latency. A new brcmfmacmpc
module parameter plus a device modprobe.d conf (mpc=0) keep it awake (the
Nexus Q is mains-powered): loss 30 %→0 %, latency 270–530 ms→4–59 ms. Stock-proven
to be a driver gap — the same firmware + nvram works under the vendorbcmdhd. - WiFi: disabled brcmfmac P2P on the BCM4330 — the firmware advertises P2P but
cannot create the P2P_DEVICE interface, which spammed the log with failed p2p-dev
creations and orphaned "event handler failed (72)" errors. - boot: silenced the benign ti-sysc active-timer
-EBUSYprobe error for
GPTIMER1 (an always-on system clockevent owned by the timer core).
Known issues
- WiFi 2.4 GHz bulk throughput is limited by Bluetooth coexistence (the BCM4330
combo shares one 2.4 GHz antenna) on a g-only AP — use 5 GHz for full speed
(~26–30 Mbit/s, 802.11n). See
docs/2026-06-26-wifi-mpc-fix-and-bulk-bufferbloat.md.
v1.4.0 — MPU cpufreq DVFS to 1.2 GHz (3.4×)
[1.4.0] - 2026-06-26
Added
- MPU CPU frequency scaling — on-demand up to 1.2 GHz (3.4× the old floor). 🚀
The OMAP4460 was pinned at its 350 MHz boot OPP; it now scales across
350 / 700 / 920 / 1200 MHz under theondemandgovernor. Built up in small,
hardware-validated stages, each cross-checked against this unit's
reverse-engineered stock kernel:- VDD_MPU is handed from the TWL6030 VCORE1 SMPS to the external TPS62361
regulator over the PRM Voltage-Controller SR-i2c — the same hand-over stock does. - A thin "VC-bridge"
cpu-supplyregulator letscpufreq-dtscale the rail
through the OMAP voltage layer (VP force-update), at the stock-measured nominal
voltages (1025 / 1203 / 1317 / 1380 mV). - At the 1.2 GHz OPP, Forward Body Bias is engaged on VDD_MPU via the on-chip
ABB LDO — required for stable 1.2 GHz operation. - Thermal throttling: at the 100 °C trip the CPU cooling drops the frequency
and ramps it back as it cools, so sustained full load stays safe.
- VDD_MPU is handed from the TWL6030 VCORE1 SMPS to the external TPS62361
- USB serial debug console. The USB gadget is now an ACM serial console
(/dev/ttyACM0on the host, with asteelhead login:prompt) that survives
reboots and leaves fastboot untouched.
Changed
- The USB gadget no longer exposes a host-side network interface — it was swapped
from the RNDIS network gadget to the serial console above. Use the on-board
ethernet / WiFi for networking.
Known issues
- On-board LAN9500A USB-Ethernet is down — a regression from 1.3.0. 🌐 The
Ethernet that 1.3.0 fixed no longer enumerates on these cpufreq builds: the
LAN9500A fails to connect (the EHCI port'sPORTSCconnect-status stays 0). It
is a boot-timing side-effect of the voltage/cpufreq changes, which tipped the
formerly-marginal connect timing into consistent failure. WiFi works in the
meantime; a fix (a settle delay in the ethernet bring-up, or reordering the
voltage init) is tracked for 1.4.1.
Full Changelog: v1.3.0...v1.4.0
v1.3.0 — Ethernet works 🌐
[1.3.0] - 2026-06-24
Fixed
- On-board LAN9500A USB-Ethernet now works on mainline 6.12 🌐 — the
long-standing "intermittent / never enumerates" problem is resolved. The
chip enumerates on every boot (0424:9e00→smsc95xx … eth0), the link comes
up at 100 Mbps/Full and passes traffic cleanly. Verified on hardware: 5/5
reboots all enumerate, 600 sustained pings at 0 % loss, 410 MB moved with
zero rx/tx/CRC/drop errors. Root cause was two combined bugs, both found by
stock-parity auditing against the factory Android kernel:- Patch 0012 (
mfd: omap-usb-host): mainline only enables the per-port
UTMI functional clock (usb_host_hs_utmi_pN_clk— the L3INIT CLKCTRL
OPTFCLKEN gate) for TLL/HSIC port modes. An external-PHY (ehci-phy)
port falls through todefault:and never gets its clock, so the port-1 UTMI
link block ran unclocked (clk_summaryshowed it disabled) and the
controller never latched the downstream connect (PORTSC CCS stuck 0). Added
OMAP_EHCI_PORT_MODE_PHYto the clock enable/disable paths. - Patch 0006 (
usb: ehci-omap): stock'somap_ehci_soft_phy_reset(the
UHH softreset / gpio pulse / clock re-park / ULPI register burst) is not
the EHCI.resethook — it is a runtimeehci_hub_controlrecovery
handler that only fires when a port reset/resume times out, after a
device has connected. We were running that whole sequence at bring-up, which
blocked the very first connect. The.resethook is now a plain
ehci_setup()bring-up (the USB3320's reset defaults already put it in host
mode); the ULPI/UHH recovery helpers are retained for a future hub_control
hook.
- Patch 0012 (
Changed
- All kernel patch headers now carry
petronijus@bastla.com(was a work email /
placeholder).
Artifacts
nexusq-boot-v1.3.0.img— kernel-only change (the ethernet fix); flash to the
boot partition. The rootfs is unchanged from v1.2.0 — reuse
nexusq-rootfs-v1.2.0-sparse.imgfrom the v1.2.0 release.
Full Changelog: v1.2.0...v1.3.0
v1.1.0 — Ethernet (LAN9500A) works 🎉
[1.1.0] - 2026-06-22
Added
-
Ethernet (LAN9500A) now works 🎉 — the soldered on-board SMSC LAN9500A
USB-ethernet enumerates and carries traffic. Two kernel changes did it:0006-usb-ehci-omap-steelhead-keep-ethernet-port-alive-ulp— steelhead
host-init inehci-omap: INSNREG01 burst thresholds, a ULPI Function-Control
soft reset of the USB3320 PHY beforeusb_add_hcd(), and
usb_disable_autosuspend()on the root hub so the idle port is not
clock-gated away.0008-mfd-omap-usb-host-steelhead-UHH-HOSTCONFIG-connect— program
UHH_HOSTCONFIGto the vendor's0x11c(setP1_CONNECT_STATUS, leave
APP_START_CLKclear) so the EHCI latches the port-1 connect. Measured
mainline default was0x1c; the stock Android 3.0 kernel uses0x11c.
The long-standing "ethernet is dead hardware" verdict was wrong — the stock
kernel enumerates the same chip on this unit, proving the HW is fine and the bug
was ours. Verified on hardware (#8 kernel):eth0(0424:9e00→smsc95xx)
links at 100 Mbps/Full and passes bidirectional traffic — 0% packet loss over a
direct cable, zero rx/tx/CRC/frame errors after ~660 MB moved. Throughput
~30–60 Mbps (USB2 / single-core OMAP4 bound, not a link fault). Reach the device
over ethernet with the persistenteth-directNetworkManager profile
(static10.42.0.2/24). -
Kernel patch
0007-clk-ti-composite-implement-divider-round-set-rate— OMAP4
ti,composite-clocknodes (gate + divider) had stubround_rate/set_rate
returning-EINVAL, so anyclk_set_rate()on them failed. Delegated both to
ti_clk_divider_ops(asrecalc_ratealready did). Fixes the TAS5713
amplifier MCLK:dpll_per_m3x2_cknow sets to 61.44 MHz →
auxclk1_ck= 12.288 MHz (256 × 48 kHz). Verified on hardware (#4 kernel):
clock rates correct, ALSA card 0NexusQ-Speakerregisters cleanly, no
couldn't set dpll_per_m3x2_ckerror. -
CONFIG_SRAM=yin the defconfig (OMAP4 on-chip SRAM driver). -
Tooling:
scripts/regen-dts-patch.sh(regenerate patch 0003 from the working
DTS) andscripts/extract-and-repack.sh(pull kernel+DTB from the build
chroot pkgdir and repack a partition-sized boot image — a fast path that skips
the rootfs build). -
Build fix: the recurring
abuild create_apks"Permission denied" on
/home/pmos/packages//pmos/armv7/...apkis fixed. On a reusednexusq-workdir
volume$WORK/packageswas owned by the containerpmos(uid 1000) while
abuild inside the chroot runs as uid 12345, so it could not write its.apk.
docker-build.shPhase 7a nowchowns$WORK/packagesto 12345 before the
build, solinux-google-steelhead-*.apkis created cleanly andpmbootstrap installruns.extract-and-repack.shis kept as a fast path, no longer a
required workaround. -
Build fix: clearing the armv7 ccache out-of-band leaves its directory owned
by uid 1000, so abuild inside the chroot (uid 12345) then hitsccache: error: Permission deniedatmake olddefconfig.docker-build.shPhase 7a now also
chowns$WORK/cache_ccache_armv7to 12345 (alongside$WORK/packages).
Changed
- DTS: delete the upstream
cpu@1node to match the single-core build
(CONFIG_SMP=n). Clears the early-DTnodes greater than max cores 1warning
and the resulting kernel taint (was 512, now 0). Re-add together with the
deferred OMAP4460 SMP / CPU1 bring-up. Patch 0003 regenerated accordingly. - Device root password is now read at runtime from a gitignored
.nexus_pw
(no hard-coded credential in the SSH/flash helpers).
Known limitations
- Rootfs image build (
pmbootstrap install, Phase 9) currently fails on a
device-google-steelheadpost-install step (exit 127); the kernel.apkand
boot image build fine, so kernel/DTB iteration is unaffected. Reflash boot only.
Install: flash nexusq-boot-v1.1.0.img to the 8 MB boot partition
(dd … of=/dev/mmcblk0p9 conv=fsync from a running system, or fastboot flash boot). The root filesystem is unchanged since v0.1.0 — reuse
nexusq-rootfs-v0.1.0-sparse.img. The boot image is kernel #8; it prints the
UHH_HOSTCONFIG values once at boot (diagnostic) and is functionally identical to
the cleaned 0008 source patch in this tag. sha256 in sha256sums.txt.
Note: the rootfs image build (pmbootstrap install, Phase 9) currently fails on
a device post-install step; the kernel/boot image build is unaffected.
Full Changelog: v0.1.0...v1.1.0
v0.1.0 — First working system
First release where the Nexus Q boots into a usable OS. From a bricked-looking black screen to postmarketOS with WiFi, Bluetooth, SSH and a desktop.
Highlights
- postmarketOS (systemd) boots from the userdata partition
- WiFi via BCM4330 with the device's original factory calibration (recovered from the intact 2012 Android system partition)
- Bluetooth with original "Proxima" firmware config
- XFCE4 desktop on HDMI, SSH over USB gadget and WiFi
- TAS5713 25 W amplifier audio path wired and software-verified
- 4 kernel patches on mainline 6.12.12 (TAS5713 support, steelhead DTS, TWL6030 32k clock cell)
Install
See INSTALL.md. Short version:
fastboot flash boot nexusq-boot-v0.1.0.img
fastboot -S 100M flash userdata nexusq-rootfs-v0.1.0-sparse.img
Default login user/147147 — change it. SSH host keys generate on first boot.
Known issues
- ~1 in 3 boots hangs (old U-Boot flakiness) — power-cycle again
- Single-core only (U-Boot leaves CPU1 in a bad state)
- On the reference unit, ethernet and the TWL6040 codec are dead hardware; your unit may differ
v1.0.0 - First Successful Build
nexusQ Reloaded - First Build
Initial successful build for Google Nexus Q.
Included artifacts
- boot.img — Boot image
- google-steelhead.img — Full system image for Google Nexus Q