From 9d5faf40cacdf505d92a1736454ab27519b06939 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin Date: Wed, 22 Apr 2026 21:24:23 +0300 Subject: [PATCH] Fix restore: compute NAND partition offsets from mtdparts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partition offsets were computed from image data sizes, which are smaller than actual NAND partition sizes (e.g. UBIFS image is 5MB but partition is 8MB). This caused kernel to be written at wrong NAND offset. Now parses mtdparts string to get real partition sizes and computes correct offsets. Handles "-(name)" fill-remainder syntax. Tested: OpenIPC NAND install on hi3516av200 — kernel at 0x200000, rootfs at 0xA00000, all correct. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/defib/cli/app.py | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/defib/cli/app.py b/src/defib/cli/app.py index a5a4a4f..e1f84ec 100644 --- a/src/defib/cli/app.py +++ b/src/defib/cli/app.py @@ -2425,12 +2425,35 @@ async def _send(cmd: str, timeout: float = 60.0) -> str: other_parts = [(i, p) for i, p in write_order if (i, p) not in boot_parts] write_order = other_parts + boot_parts - # Pre-compute partition offsets from original sequential order + # Pre-compute partition offsets from mtdparts if available, else from data sizes _part_offsets: dict[int, int] = {} - _off = 0 - for i, (_, pdata) in enumerate(partitions): - _part_offsets[i] = _off - _off += len(pdata) + if mtdparts_arg and detected_flash == "nand": + import re as _re_off + _pstr = mtdparts_arg.split(":", 1)[1] if ":" in mtdparts_arg else mtdparts_arg + _cur = 0 + for _i, _pd in enumerate(_pstr.split(",")): + _part_offsets[_i] = _cur + _fm = _re_off.match(r"-\(", _pd.strip()) + if _fm: + break # fill remainder — no more offsets to compute + _pm = _re_off.match(r"([\d]+)([kKmM]?)", _pd.strip()) + if _pm: + _sz = int(_pm.group(1)) + _u = _pm.group(2).upper() + if _u == "M": + _sz *= 1024 * 1024 + elif _u == "K": + _sz *= 1024 + _cur += _sz + # Fill remaining indices from cumulative + for _i in range(len(partitions)): + if _i not in _part_offsets: + _part_offsets[_i] = _cur + else: + _off = 0 + for i, (_, pdata) in enumerate(partitions): + _part_offsets[i] = _off + _off += len(pdata) for part_idx, (name, data) in write_order: # Pad to page alignment for NAND (2KB pages)