Files
Dejvino 1eb6ba6b9f Review must-fix: LICENSE, dangling ref, obsolete markers
- LICENSE (MIT, own work) + README license section
- FINDINGS.md per-version notes point into docs/firmware/
- checksum brute-forcers marked superseded (code + tool docs)
2026-09-30 22:52:21 +02:00

6.4 KiB
Raw Permalink Blame History

Lofi-12 XT — Findings Library

Living knowledge base for this device. Process/tips live in RE-PROCESS.md. Per-version structural notes: docs/firmware/notes-v{1.1.156,1.2.179,1.5.205}.md; version diff: rev-diff.md; mod feasibility: tweakability-report.md; tool docs: tools/README.md. Deep dives: docs/hardware.md, docs/bootloader.md, docs/firmware-update.md, docs/firmware/v1.5.205.md.

1. Hardware

  • Device: Sonicware Lofi-12 XT (shares platform with SmplTrek/Cydrums).
  • Main SoC (core module): TI TMS320C6748 — ARM9 + C674x DSP. Marking on unit: TMS320 C6748EZW T / 13CP99W / GI 375 / 527 ZWT.
  • DRAM (core module): EtronTech EM68C16CWQG-25H — 1 Gbit DDR2, base 0xC0000000.
  • SPI flash (core module, 2×): Macronix MX25L12833F (MXIC MX 25L12833F M2I-10G), 16 MByte each, SOIC-8, silkscreen IC300 / IC301. Shipping units hide the marking under small stickers (C047/C949-style labels) — peel + photo to confirm.
  • USB/aux MCU (main board): ARTERY AT32F421K8T (own firmware, out of scope).
  • Storage: full-size SD slot (firmware update + samples/projects).
  • PCBs seen: 405-VTOR-3852 (I/O), 405-VTOR-3849B (main), 405-VTOR-3853 (jack), core module with CN201A/CN200A/CN203A/CN203B board-to-board connectors.
  • Silkscreen pin tables on main board expose UART1_RX1/TX1, SPI1_SCK/MOSI, SD_*, USB_DP/DN, key/LED matrix — worth mapping before any invasive work.

2. Memory map (DDR2)

Region Content
0xC0000000… DDR2 base (128 MB)
0xC2xxxxxx SD .bin application image (DSP). v1.5 code C2B80C00, strings C2D84DE0, assets C2DA7600
0xC7074630–C70B0598 SPI AIS bootloader image (DSP), entry C70A28A0
0xC706F280 Runtime constant seen in updater (also == checksum seed, §5)
0xC27C6282 Scratch DDR used by updater (§5; value doubles as checksum seed)

3. SPI flash layout (ic300.bin / ic301.bin, 16 MiB each)

Dumps: ic300.bin (c2b86808…), ic301.bin (81f7b1f5…). Always keep these as recovery backups; re-verify with a second read (sha256sum + cmp).

IC300 (boot + app): TI AIS image, magic 0x41504954 (TIPA) at file 0x0. PLL/DDR config (0x5853590D ×2), then 10× Section Load (0x58535901):

File off DDR Size
0x000050 C7074630 0x1D0
0x00022C C7074800 0x33B00 (main code)
0x033D38 C70A8300 0x28CC (rodata)
… C70AABD0/C70AABE0/C70AABF0 0xC/0xC/0xD44
… C70AF000/C70AF4E8/C70AF5EC/C70AF660 0x200/0x104/0x70/0xF38

JumpClose (0x58535906) at file 0x38660 → entry C70A28A0 (DSP reset prelude ZERO b0; mvc b0,ier; mvc b0,csr). After it: FF gap to ~0x100000, data to ~0x1EFFFF, FF gap 0x1F–0x4Fxxxx, data 0x500000–0xFC7C17. No AIS CRC opcodes.

IC301 (data): AILS header + drum-pattern names (KICK/HIHAT/BALLAD/BLUES/…), 24× RIFF/WAVE starting 0x8007E0, nearly full to 0xFFFD7B. Factory-sample flash.

Update path (from updater strings + code): SystemUpdater::{start, updateBootSection, updateMainSection, updatePresetSection, updateMCUSection, updateMCUBootSection}(CatMetaData::ROMSection) + SystemVerify::verifyPresetSection. Public ZIPs ship only the SYSTEM section (the SD .bin); BOOT/PRESET/MCU use separate (unreleased) files. Updater lives in AIS flash, so a bad SYSTEM image cannot kill recovery — hold PAD while powering on → SYSTEM UPDATE still works.

4. SD .bin container (cmtd/mmtd/sect → EOF)

Off Field
0x00 cmtd magic
0x04 u32 LE filesize (must match actual)
0x08 u32 checksum — solved, §5
0x0C reserved 0
0x10–0x2F 12, 1, 3, fw_maj, fw_min, fw_patch, 48, remaining
0x30 mmtd magic; +0x04 remaining; +0x08 flags (per-build, part of hash)
0x40 fw triple; 0x4C entry point; 0x50 sect count
0x54… sect ×N: 73 65 63 74 + u32 load_addr + u32 len + payload; must tile EOF

Known builds: v1.1.156 (1,595,605 B, entry C26C4820, 7 sects), v1.2.179 (1,606,197 B, entry C26CA4C0, 6 sects), v1.5.205 (1,707,049 B, entry C2CD1AA0, 7 sects). Code is C674x LE, entropy ~6.89, unencrypted. Parser/packer: tools/lofi_image.py (parse_image asserts filesize + chain fit).

5. Checksum (SOLVED)

Rule: cmtd+0x08 = CRC32-IEEE (init 0) over the entire file with bytes [8:12] replaced by 0xC27C6282.

  • tools/lofi_image.py: CKSEED = 0xC27C6282, compute_checksum(); build_image() auto-computes by default (--checksum keep in lofi_pack.py preserves).
  • Proof: GF(2) linear solve per image for the 32 unknown bits at [8:12] gives K = 0xC27C6282 on all three images independently (2⁻⁶⁴ fluke); forward recompute reproduces F58AF539 / DFF0D8C2 / B17C0857; unpack→pack rebuilds stock v1.5.205 byte-identical; a Threshold→ThresholX mod forges to a self-consistent 462F735B.
  • Code anchors (bootloader DSP): CRC routine C70A0A60 (NOT A6→state, poly EDB88320 via MVK/MVKH, byte loop, final NOT in delay slot ≡ zlib chaining F(buf,len,init)); 4K-chunk caller C708E4E4 (MVK 0x1000, CMPGT, CALLP C70A0A60); check fn C709E7C0 (16-byte header CRC init 0 → chained 0x40000 chunks → CMPEQ A13,A12 compare); orchestrator C708678C CALLP C709E7C0, reject path builds ERROR : This file is invalid. (C70A8E82).
  • Forging: build image normally, then set [8:12] = compute_checksum(image).

6. OLED / updater UI strings (orientation)

Checking... 0%, Check the firmware file., ERROR : This file is invalid., Erasing.../Writing.../Verifying... 0%, 100%, done./OK./NG., Update completed./Update failed., Please restart., Are you sure?, [CLR] : No / [OK] : Yes, >> BOOT/MCU/MCU Boot/PRESET/SYSTEM, BOOT:/MCU:/MCU Boot:/PRESET:/SYSTEM:, $ systemupdate, [Lofi-12 XT] ~, SYSTEM INFO/VERSION/BOOT/SYSTEM/MCU, crash dumper (Legacy NMI Exception, A0–A31/B0–B31, NTSR/ITSR/…). v1.5-only markers: AppAudioExport*, MIsolator/MRackComp/SlipRoll/HoldDelay, MIDINoteMap, REVERSE, removeResourceFork (all present in IC300 → board runs v1.5).

7. Open questions

  • mmtd+0x08 flags semantics (timestamp? covered by checksum as-is, no need to crack).
  • Exact flash section table for BOOT/PRESET/MCU offsets (only SYSTEM reverse-engineered).
  • AT32F421 firmware extraction/update protocol.
  • UART/JTAG test-point mapping (silkscreen names exist, continuity not traced).