You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Finalize locked CFW boot files via a pre-HOS swap payload
package3 and stratosphere.romfs are locked while Atmosphere runs and can't
be replaced in-session (proven by the [boot] logs). The boot payload must
match package3, so updating fusee/reboot_payload while package3 stays old
is the "incorrect fusee version" brick -- including via an RCM-injected
fusee.bin.
Fix: stage the whole version-matched boot set (package3,
stratosphere.romfs, reboot_payload.bin, root fusee.bin) as .ab_new and
never write any of them in place, so the old matched set always stays
consistent. Reboot into TegraExplorer (bundled, GPL), whose sd:/startup.te
renames the sidecars into place before HOS boots -- when they're unlocked
-- then chainloads the now-consistent CFW. Arming uses Atmosphere's bpc:ams
(amsBpcSetRebootPayload), done dead-last in main() after smExit(); Daybreak's
post-install reboot lands in the payload, so CFW + firmware still take one
reboot. CFW-only updates reboot via cfwMgrReboot.
If anything fails (arming, missing payload, power loss) the old set is
intact, so it just boots the old CFW and retries -- it cannot brick.
- lib/ams_bpc.{c,h}: vendored Atmosphere reboot-to-payload interface
- source/payload_swap.{c,h}: swapPending/swapPrepare/swapArm + startup.te
- romfs/TegraExplorer.bin: stock TegraExplorer v4.2.0 (GPL, suchmememanyskill)
- extract.c: force-stage the boot set, keep it off pending.txt
- firmware_mgr/cfw_mgr/main: arm the swap, clean up stray startup.te
Bump to 2.1.0.
Copy file name to clipboardExpand all lines: README.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -115,18 +115,18 @@ Atmosphere has to be updated before the reboot that loads the new firmware. New
115
115
116
116
Extracting the CFW package just places files on the SD card; it doesn't touch the currently running system. The old Atmosphere keeps running in memory while you do everything else. The new files only matter at boot, which is why you can do CFW → firmware → one reboot back to back.
117
117
118
-
### How AetherBlock Handles Locked Files
118
+
### How AetherBlock Handles Locked Boot Files
119
119
120
-
A couple of Atmosphere files (`package3`, `stratosphere.romfs`, and sometimes `AetherBlock.nro` itself) are held open by the running CFW and can't be overwritten with a plain file write. AetherBlock handles this transparently:
120
+
`package3` and `stratosphere.romfs` are held open by the running Atmosphere and **cannot** be overwritten, renamed, or deleted while CFW is running — every in-session trick (plain write, stash-and-rename, libnx direct write) fails on them. The boot payload (`fusee.bin` / `reboot_payload.bin`) is the version-matched partner of `package3`; if the payload updates but `package3` doesn't, the console boots to a "incorrect fusee version" fatal. The only safe place to replace `package3` is **before HOS boots**, so AetherBlock finalizes the swap from a reboot payload:
121
121
122
-
1. During CFW extraction, it first tries a direct write, then a stash-and-rename, then a libnx direct-write path that bypasses stdio's share semantics. Most files land at that stage.
123
-
2.For anything that still refuses to budge, the new content is staged as `<file>.ab_new` and queued in `/config/AetherBlock/pending.txt`.
124
-
3.Right before the post-Daybreak reboot, AetherBlock tries to swap the staged files into place using a backup-rename-restore pattern so the real file is never in a missing state.
125
-
4.On the next launch after reboot, any sidecars that are still around get one more attempt — including a byte-for-byte content check so redundant `.ab_new` files get cleaned up automatically.
122
+
1. During CFW extraction the whole version-matched boot set — `package3`, `stratosphere.romfs`, `atmosphere/reboot_payload.bin`, and the root `fusee.bin` — is staged as `<file>.ab_new` next to the originals and **never written in place**, even the files that aren't locked. That's deliberate: it guarantees neither the reboot payload nor an RCM-injected `fusee.bin` can ever get ahead of `package3`. The old, matched set stays fully in place — the running CFW is never left inconsistent, and no reboot path (normal, RCM jig, or cold boot) can pair a new fusee with an old `package3`.
123
+
2.AetherBlock writes `sd:/startup.te` (a TegraScript) and arms **TegraExplorer** as the next reboot payload via Atmosphere's `bpc:ams` extension (`amsBpcSetRebootPayload`). Arming is done dead-last, after every other service is torn down, because it requires `smExit()`.
124
+
3.The single reboot — Daybreak's post-install reboot, or AetherBlock's own for a CFW-only update — lands in TegraExplorer instead of fusee. Before any menu is drawn, `startup.te` renames each `.ab_new` into place (now unlocked, because HOS hasn't booted) and chainloads the now-consistent CFW.
125
+
4.If anything goes wrong — arming fails, the payload is missing, power is lost — the old set is still intact, so the console simply boots the **old** CFW and the `.ab_new` files wait for a retry. A new fusee never meets an old `package3`, so this path **cannot brick**.
126
126
127
-
Critically, libnx never flushes SD writes to the card on its own — `fclose` only drops the data into the filesystem cache. After every extraction, after every staged swap, and one final time right before control passes to Daybreak's reboot, AetherBlock calls `fsdevCommitDevice("sdmc")`to force everything to physically persist. Without this, a large file like the 8 MB `package3` can read back stale after the reboot even though every write reported success — leaving a new `fusee` paired with an old `package3` and the dreaded "incorrect fusee version" boot error.
127
+
libnx also never flushes SD writes on its own (`fclose` only fills the FS cache), so AetherBlock calls `fsdevCommitDevice("sdmc")`after extraction, after writing `startup.te`, and on every log line, to guarantee everything is physically on the card before the reboot.
128
128
129
-
The net effect: you never have to manually rename anything, stale sidecars don't accumulate on the SD card, and the boot files are guaranteed on-disk before the reboot.
129
+
The bundled `romfs/TegraExplorer.bin` is the stock [TegraExplorer](https://github.com/suchmememanyskill/TegraExplorer) v4.2.0 release (GPL-2.0) by suchmememanyskill — used unmodified; it auto-runs `sd:/startup.te` on boot.
0 commit comments