This commit is contained in:
Dejvino
2026-09-30 22:48:06 +02:00
commit 8913cb4314
37 changed files with 3190 additions and 0 deletions
+53
View File
@@ -0,0 +1,53 @@
# Firmware update (SD path)
How a stock or modded `.bin` gets onto the device and exactly what is verified.
No hardware access needed — SD card + OLED only.
## Trigger
File named `Lofi-12 XT.bin` at SD root (from the official update ZIP:
https://sonicware.jp/pages/downloads), then hold **PAD while powering on**.
Updater (`SYSTEM UPDATE`) lives in SPI AIS flash, **not** in the `.bin`, so a
bad SYSTEM image can always be reverted with a stock SD.
## Stages (OLED text)
1. `Checking... 0%` — parse + validate the file (checks below). Failures:
`The firmware file not exist.`, `This card is invalid format.`,
`ERROR : This file is invalid.` / `Check the firmware file.`
2. `Are you sure?` — `[CLR] : No / [OK] : Yes`.
3. Per section (`>> BOOT / SYSTEM / PRESET / MCU / MCU Boot`, prompts `BOOT:`…):
`Erasing...`, `Writing...`, `Verifying...` with `%` progress.
4. `100%, done.` / `Update completed.` (`100%, NG.` / `Update failed.` on error)
→ `Please restart.`
## Checks performed on the `.bin`
1. Magic: `cmtd` @`0x00`, `mmtd` @`0x30`, `sect` chain from `0x54`.
2. `cmtd+0x04` filesize equals actual file size.
3. `sect` chain tiles EOF exactly (`next = off + 12 + len`); load addresses must
land in DDR (`0xC2xxxxxx`); entry point must sit inside the code sect.
4. **Checksum** `cmtd+0x08` — recomputed and compared (`CMPEQ`, reject =
`ERROR : This file is invalid.`). Rule (proven 3/3, see below):
CRC32-IEEE, init 0, over the whole file with bytes `[8:12]` replaced by
`0xC27C6282`. `mmtd+0x08` flags are covered as-is (no special handling).
## Forging a valid image
```bash
python3 tools/lofi_patch_string.py stock.bin mod.bin OldString NewStringX
python3 tools/prove_checksum.py mod.bin # expect MATCH
```
`lofi_pack.py`/`lofi_patch_string.py` stamp the checksum automatically
(`lofi_image.compute_checksum`); `--checksum keep` preserves the old value.
`analysis/solve_ckseed.py` re-derives the seed constant from any stock image
(GF(2) solve, expect `C27C6282`).
## Notes
- Public ZIPs ship only the SYSTEM section; BOOT/PRESET/MCU use separate files.
- Only same-length string/asset/constant edits keep every address stable
(Level-0). Longer content needs slack-space pointer patching (`lofi_xref.py`).
- The AT32 USB MCU updates through `updateMCUSection` — protocol unreversed;
leave MCU sections alone.