52 lines
2.5 KiB
Markdown
52 lines
2.5 KiB
Markdown
# Bootloader
|
||
|
||
How the device boots, from power-on to app. Static analysis of the IC300 SPI
|
||
dump (kept local, never shipped) + TI C6748 public boot docs.
|
||
|
||
## Chain
|
||
|
||
1. **SoC ROM (ARM9)** reads boot-mode pins → SPI flash master mode.
|
||
2. ROM parses the **AIS image** at flash `0x0` (magic `0x41504954`, `TIPA`).
|
||
3. AIS prelude runs **PLL/DDR/EMIF init** (opcodes `0x5853590D` ×2 at file
|
||
`0x8`/`0x1C`), so DDR is usable before any load.
|
||
4. ROM processes **10× Section Load** (`0x58535901`), copying code/data to
|
||
`0xC7074630–0xC70B0598` (see table below), then **JumpClose** (`0x58535906`,
|
||
file `0x38660`) to entry **`C70A28A0`**.
|
||
5. Entry is DSP code (C674x reset prelude `ZERO b0; mvc b0,ier; mvc b0,csr`,
|
||
stack align) — from here the DSP owns the system; ARM ROM's job is done.
|
||
No AIS CRC opcodes are present.
|
||
|
||
## AIS section table (file off → DDR, size)
|
||
|
||
| File | DDR | Size | Role |
|
||
|---|---|---|---|
|
||
| `0x000050` | `C7074630` | `0x1D0` | header/code |
|
||
| `0x00022C` | `C7074800` | `0x33B00` | main code (updater lives here) |
|
||
| `0x033D38` | `C70A8300` | `0x28CC` | rodata (strings, vtables) |
|
||
| … | `C70AABD0`/`C70AABE0`/`C70AABF0` | `C`/`C`/`D44` | small records |
|
||
| … | `C70AF000`/`C70AF4E8`/`C70AF5EC`/`C70AF660` | `200`/`104`/`70`/`F38` | tables/tail |
|
||
|
||
Re-split any dump with `tools/ais_unpack.py`.
|
||
|
||
## What the bootloader contains
|
||
|
||
- Full C++ application core (libc++, TI CGT): `Foundation::SystemUpdater`,
|
||
`SystemVerify`, `BootLoader(Delegate)`, HAL drivers (`N3HAL` SPI/I2C/UART/SD),
|
||
OLED/display stack, crash dumper (`Legacy NMI Exception`, register dump).
|
||
- Updater methods per flash section: `updateBootSection`, `updateMainSection`
|
||
(the SD `.bin` = SYSTEM), `updatePresetSection`, `updateMCUSection`,
|
||
`updateMCUBootSection`, all taking `CatMetaData::ROMSection`.
|
||
- Checksum engine: bitwise CRC-32/IEEE at **`C70A0A60`**
|
||
(`NOT` init/final in/around the routine ⇒ zlib chaining `F(buf,len,init)`),
|
||
4 KiB-chunk driver at **`C708E4E4`**, file check at **`C709E7C0`**
|
||
(16-byte header CRC seed 0 → chained `0x40000` chunks → `CMPEQ` vs stored),
|
||
orchestrated from **`C708678C`**. Ghidra decompilations that proved this are
|
||
described in `RE-PROCESS.md` §3–4 (project kept local).
|
||
|
||
## Rest of IC300 flash
|
||
|
||
Past the AIS image: `FF` to `~0x100000`, data to `~0x1EFFFF`, `FF` gap
|
||
`0x1F–0x4Fxxxx`, data `0x500000–0xFC7C17` (app/data sections loaded by the
|
||
updater; exact section table not yet mapped — open question in `FINDINGS.md`).
|
||
IC301 is separate factory content (`AILS`, pattern names, 24 WAVs).
|