Skip to content

dump-flash, restore: stage in the board's own DRAM - #149

Merged
widgetii merged 3 commits into
masterfrom
dump-flash/ram-staging
Oct 14, 2026
Merged

widgetii merged 3 commits into
masterfrom
dump-flash/ram-staging

Conversation

@widgetii

Copy link
Copy Markdown
Member

dump-flash (over a U-Boot console) and restore both staged at a fixed 0x82000000. DRAM on ev200-era parts starts at 0x40000000, so on those boards the address has no memory behind it.

Found on a gk7201v200 (XM U-Boot 2020.01, xm72010200): defib dump-flash -p /dev/ttyUSB3 --size 8MB ran sf read 0x82000000 0x0 0x800000, every md.b chunk came back empty, the output stayed 0 bytes, and U-Boot wedged until a power cycle.

dump-flash

  • The CLI now passes -c through to dump_flash().
  • Without a chip, dump_flash() asks the running U-Boot instead of guessing. It tries bdinfo's DRAM bank start first, then the env's soc=, accepted only if the exact RAM table or a profile knows it. XM's vendor U-Boot has no bdinfo but does carry soc=.
  • If neither works, it refuses before any sf read and asks for -c.

restore

  • restore always has -c, so it now uses get_ram_staging_addr(chip), as install already does.
  • Chips whose DRAM starts at 0x80000000 still get 0x82000000.

Testing

  • New tests cover the bdinfo path, the XM env-soc path, the refuse paths, explicit -c, and the CLI passing -c through.
  • tests/test_restore_ram_staging.py runs the real restore command against a scripted U-Boot console for gk7201v200, hi3516ev300 and hi3516cv300. On the old code it fails for the two 0x40000000 chips.
  • pytest (1031 passed), ruff and mypy are clean.
  • dump-flash was checked on the gk7201v200 board: without -c it logged "SoC from U-Boot env: gk7201v200", staged at 0x42000000, passed 16/16 CRC32 blocks, and two runs were byte-identical.
  • restore was not run on hardware, because it erases flash.

Over a U-Boot console, dump-flash never handed -c to dump_flash(), which
then staged at a fixed 0x82000000. DRAM on ev200-era parts starts at
0x40000000, so on a gk7201v200 (XM U-Boot 2020.01, xm72010200)

    defib dump-flash -p /dev/ttyUSB3 --size 8MB

ran `sf read 0x82000000 0x0 0x800000`, every md.b chunk came back empty
("Retry 1: no data at 0x1000"), the output stayed 0 bytes and U-Boot
wedged until a power cycle.

The CLI now passes -c through, which already resolves gk7201v200 to
0x42000000 via its profile. Without a chip, dump_flash() asks the running
U-Boot instead of guessing: bdinfo's DRAM bank start first, then the env's
soc= resolved through the exact RAM table or a profile only (no loose
prefix match). XM's vendor U-Boot has no bdinfo but does carry
soc=gk7201v200. If neither answers it refuses before any sf read and asks
for -c.

Verified on the gk7201v200 board above: without -c,

    defib dump-flash -p /dev/ttyUSB3 --size 0x10000

logged "SoC from U-Boot env: gk7201v200", staged at 0x42000000, passed
16/16 per-block CRC32 checks, and two runs were byte-identical.
restore hardcoded ram_addr = 0x82000000 for every tftpboot and every
sf/nand/mmc write. On parts whose DRAM starts at 0x40000000 (gk7201v200,
gk7205v200, hi3516ev300, ...) that is an address with no memory behind it
-- the same mistake that wedged U-Boot under dump-flash. restore always
has -c, so use get_ram_staging_addr(chip), as install already does.
0x80000000-family chips still get 0x82000000, so nothing changes there.

tests/test_restore_ram_staging.py drives the real restore command against
a scripted U-Boot console and checks the load and write addresses for
gk7201v200, hi3516ev300 and hi3516cv300, and that boot is still written
last.

Not run on hardware: restore erases flash, and the change is covered by
the end-to-end test above.
@openipc-ai

Copy link
Copy Markdown
Contributor

/review

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. A mistyped chip can wedge U-Boot ✓ Resolved
Description
_dump_flash_async now passes any -c value to dump_flash, where get_ram_staging_addr silently
returns 0x82000000 for an unrecognized name. On a gk7201v200 board, a typo such as -c gk7201v201
passes the UART routing check and sends sf read to that address instead of the profile-derived
0x42000000.
Code

src/defib/cli/app.py[833]

+            flash_size=flash_size, chip=chip,
Evidence
A missing profile is classified as UART, so the CLI reaches the newly added chip argument. The
staging helper returns a fixed address when neither its exact lookup nor its prefix lookup matches;
dump_flash uses that address directly in sf read. The gk7201v200 profile instead places U-Boot
in the 0x40000000 region, from which the helper derives 0x42000000.

src/defib/cli/app.py[775-779]
src/defib/profiles/loader.py[111-118]
src/defib/flashdump.py[111-126]
src/defib/flashdump.py[544-549]
src/defib/flashdump.py[567-578]
src/defib/profiles/data/gk7201v200.json[1-1]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
An unrecognized `-c` value can bypass RAM detection and select the unsafe default address for a serial flash dump.
## Fix Focus Areas
- src/defib/cli/app.py[830-835]
- src/defib/flashdump.py[111-126]
- src/defib/flashdump.py[544-549]
## Recommended Fix
For serial dumps, accept a supplied chip for RAM selection only when it resolves exactly through the RAM table or a profile. Otherwise, detect RAM from U-Boot or fail before issuing `sf read`; do not use the prefix or fixed-address fallback for an unrecognized selector.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can switch off images and animations for a plain-text comment

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/defib/cli/app.py
Passing -c through meant a mistyped chip (-c gk7201v201 on a gk7201v200)
fell into get_ram_staging_addr()'s prefix and fixed-0x82000000 fallbacks,
and the sf read went back to the address that wedges U-Boot on
0x40000000-DRAM parts. dump_flash() now accepts a chip only through the
exact RAM table or a profile; anything else is logged and handed to the
same U-Boot detection as no -c at all (bdinfo, then env soc=), which
refuses before any sf read when it cannot tell.

restore keeps get_ram_staging_addr(): it cannot get that far with an
unknown chip, since loading U-Boot already needs the chip's profile.
@widgetii
widgetii merged commit 4d739ea into master Oct 14, 2026
13 checks passed
@widgetii
widgetii deleted the dump-flash/ram-staging branch October 14, 2026 11:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants