TL;DR: I rebuilt Jeeves — my GL-iNet GL-X3000 5G backup
uplink — on the
latest OpenWrt 25.12, jumping the kernel from 6.12.85 to 6.12.94. My 20
device-enablement commits rebased cleanly onto 155 upstream commits. One
build trap cost me a rebuild. Then I flashed the running router and checked
the telemetry to confirm the 5G leg came back unchanged. The image is
jeeves-r6 on the
releases page.
Why rebuild¶
The April migration put Jeeves on vanilla OpenWrt 25.12 with the Quectel RM520N-GL modem fully working. Since then upstream moved 155 commits and bumped the kernel from 6.12.85 to 6.12.94. None of it changes what Jeeves does — it’s hygiene. But hygiene isn’t free when your stack carries two out-of-tree kernel patches.
Mine has 20 commits on top of upstream, and two are the ones I watch on every rebase:
- one teaches the generic MHI PCI driver to claim the RM520N-GL by its Qualcomm subvendor ID, so the modem binds at all;
- one disables PCIe runtime power management on this board. Without it the port suspends the modem into D3hot and the MHI link dies in a completion-timeout / AER cascade that only a reboot clears.
Lose the second and the modem crashes the way it did before I found the fix. They rebased without conflict this time — and I’ve opened an issue to upstream both, because the right long-term fix is to not carry them at all.
The one build trap: a stale configure cache¶
The first build failed — in vim, not in my code. Upstream had added
-Wl,-z,max-page-size=4096 to the target CFLAGS/LDFLAGS. Most OpenWrt
packages re-run configure every build and never notice, but vim keeps its
autotools config.cache around, and with the flags changed underneath it,
configure bailed:
configure: error: changes in the environment can compromise the build
configure: error: run 'make distclean' and/or 'rm auto/config.cache'
My build container still had a build_dir from the r5 era, so the stale cache
was sitting right there. A make clean wipes the target build_dir and forces
every package to reconfigure against the new flags — the toolchain is
preserved, so it costs time but not a from-scratch rebuild. If a lone package
fails at configure with that message after a rebase, don’t hunt your patches;
clean the tree.
Flashing without losing the box¶
A firmware write reboots the device, and if the modem doesn’t come back you need physical recovery. The sequence I used:
- Pull a full config backup off the device first, so a reflash to the previous image can restore state.
sysupgrade --testthe image on the device to check metadata and board match before touching flash.- Flash over a synchronous SSH command, not a detached one.
sysupgradehands the write to a second stage over ubus; detach the session and that call silently no-ops. Let the connection block — it drops on reboot, which is normal. - Keep config on upgrade, then wait and watch.
It came back in about seventy seconds.
Did the radio survive?¶
A kernel bump touches every modem driver — MHI, MBIM, USB — so the only real
check is the numbers, not the boot log. The modem re-enumerated over PCIe/MHI
cleanly and dmesg showed the link come up with no AER cascade — the
runtime-PM patch earning its keep across the jump. ModemManager had it
connected on LTE+5G-NSA within about ten seconds.
Then I compared telemetry from before and after. The n78 NSA carrier — the whole point of this box — was statistically identical: RSRP around −95 dBm, SINR around 11.8 dB, NR attached 100% of the time on both sides.
One thing nearly fooled me: the post-flash window showed more LTE carrier aggregation, which looks like a win. It isn’t — a week of history showed the pre-flash sample had just landed in a single-carrier lull, while the box normally aggregates one to three LTE carriers depending on the network. CA depth is network-driven, not firmware. The honest verdict is no change — exactly what a pure upstream catch-up should produce. I’ve scheduled a follow-up over a full 24-hour window to confirm; 35 minutes after a reboot isn’t a radio verdict.
What rode along¶
Because my custom feeds track their main branches, a few of my own tools
advanced with the build — notably
quectel-5g-tools went 1.4.0 →
1.6.0, pulling in the Grafana dashboard generator and this cycle’s stats work.
Deliberate: I want my own code current on every build, even when upstream
hasn’t moved.
jeeves-r6 is on the
releases page. Keep the
previous image around for rollback — and think about your own setup before you
flash. I could take the remote-flash risk because Jeeves is my backup path
and I was on-site; if that box is the only thing standing between you and the
internet, treat it accordingly.