Skip to content

gk7205v500 NAND: FIT kernel volume, CMA, and sysupgrade for UBI layouts - #2526

Merged
widgetii merged 5 commits into
masterfrom
nand/ubi-fit-sysupgrade
Oct 3, 2026
Merged

widgetii merged 5 commits into
masterfrom
nand/ubi-fit-sysupgrade

Conversation

@widgetii

@widgetii widgetii commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

Fixes #2524. gk7205v500 NAND gets a bootable layout, the whole DDR, and a working sysupgrade, for both UBI layouts.

Needs OpenIPC/u-boot-xmedia#10 (FIT boot from the UBI kernel volume) for the new NAND image to boot from that U-Boot's default env.

Commits

  1. gk7205v500: CMA media memory, so Linux gets the whole DDR.
    • CMA in the kernel.
    • load_goke switches a command line that names no allocator to CMA for the next boot. mmz_allocator=xmedia keeps the carve-out.
    • hisilicon-opensdk bumped to dfc3a81 (gk7205v500: build the CMA allocator into osal openhisilicon#236), which builds the gk7205v500 osal's CMA allocator.
    • On a V510, Linux goes from 28 MB to 125 MB.
  2. init: a ubiblock root keeps its overlay in rootfs_data, as UBIFS.
    • Before this, gluebi's mtd for that volume sent init down the jffs2 branch.
    • That branch erased the overlay, and the claim with it, on every boot.
  3. gk7205v500: NAND image carries a hashed FIT kernel in a UBI volume.
    • The image now has kernel (FIT: zImage + DTB, crc32 + sha1), rootfs (UBIFS) and rootfs_data volumes.
    • The -nand- package carries fitImage + rootfs.ubifs for sysupgrade, plus rootfs.ubi for fresh installs.
  4. sysupgrade: UBI NAND layouts, written from a handed-off PID 1.
    • Supports the UBIFS layout (FIT + UBIFS, -nand- package) and the squashfs-over-ubiblock layout (NOR package).
    • ubiupdatevol needs its volume exclusively, and a mounted rootfs volume is always in use.
    • So, like OpenWrt's procd/upgraded, PID 1 is handed to a RAM root first: an inittab ::restart:/sbin/init entry, SIGQUIT, then a lazy unmount of the old root.

Hardware verification

GK7205V510 + GD5F1GM7 NAND, 128 MiB DDR, U-Boot from u-boot-xmedia#10. Each case below was a real sysupgrade over HTTP:

case result
UBIFS layout, --url=…-nand-ultimate.tgz hand-off, FIT + UBIFS written, U-Boot crc32+ sha1+ OK, new build boots, overlay/claim kept, 0 ECC/CRC/oops
ubiblock layout, --url=…-nor-ultimate.tgz hand-off, uImage + squashfs written, new build boots, overlay/claim kept, 0 errors
-n on the UBIFS overlay hand-off, rootfs_data erased, next boot "default file-system created"
first boot onto CMA (old mem=32M env) 29 modules, no oops, load_goke switches the env
CMA boot 96 MiB reserved at 0x42000000, MMZ allocated from it, ~97 MB available (was ~15 MB)

The -nand- unpack (fitImage + rootfs.ubifs, ~14 MB) was refused on mem=32M by sysupgrade's RAM check, correctly. It fits once the board runs CMA.

Tests

  • test_sysupgrade.sh: 240 checks, 16 of them new for the UBI layouts:
    • layout detection, packages, refusals;
    • hand-off staging;
    • stage-2 order (release, then kernel, then rootfs, then reboot);
    • overlay truncate;
    • -nand- URL, and the rootfs.ubi exclusion.
  • Green against both the tree copy and the comment-stripped copy.
    One transient failure in 9 local runs did not reproduce.
  • test_shell_parse.sh and test_strip_shell_comments.sh pass.

Notes

  • On this board the encoder logs Timeout from venc channel 0 with and without CMA and on the old kernel too. That's a separate (sensor/ISP) problem, not part of this PR.

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

Copy link
Copy Markdown

PR Summary by Qodo

Bootable gk7205v500 NAND images with CMA and UBI sysupgrade

✨ Enhancement 🐞 Bug fix 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Build a hashed FIT kernel and UBIFS NAND image that boots from UBI volumes.
• Enable CMA media memory so Linux can use the board’s full DDR.
• Safely upgrade both UBI rootfs layouts and preserve ubiblock overlays across boots.
Diagram

graph TD
  A["Upgrade images"] --> B["Validate layout"] --> C{"Mounted volume?"}
  C -->|No| G["Write UBI volumes"] --> H["Reboot"]
  C -->|Yes| D["Pivot RAM root"] --> E["Restart PID 1"] --> F["Release old root"] --> G
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Adopt OpenWrt’s procd/upgraded hand-off
  • ➕ Uses an established PID 1 upgrade mechanism.
  • ➖ Requires changing this firmware’s BusyBox init stack and increases the integration scope.
2. Replace the entire UBI image on upgrade
  • ➕ Uses the same image as a fresh installation.
  • ➖ Cannot safely replace the live UBI layout in place and risks losing the persistent overlay.

Recommendation: Keep the volume-level writes and BusyBox init hand-off: they fit the existing runtime and preserve rootfs_data. The critical review focus is whether every refusal occurs before the hand-off and whether the old root is reliably released before ubiupdatevol.

Files changed (14) +938 / -37

Enhancement (6) +489 / -26
MakefilePackage FIT NAND volume images alongside the install image +24/-0

Package FIT NAND volume images alongside the install image

• Adds size checks and a NAND archive containing checksummed fitImage, rootfs.ubifs, and rootfs.ubi artifacts when a FIT image is present.

Makefile

inittabAllow BusyBox init to restart into the RAM flash phase +6/-0

Allow BusyBox init to restart into the RAM flash phase

• Adds the restart action required for SIGQUIT to hand PID 1 to sysupgrade after a RAM-root pivot.

general/overlay/etc/inittab

sysupgradeSafely flash both UBI layouts from a released root +366/-22

Safely flash both UBI layouts from a released root

• Detects UBIFS and ubiblock layouts, chooses their packages, validates volume images, and writes through ubiupdatevol. For mounted rootfs or overlay volumes, stages a RAM root, hands execution to PID 1, releases the old root, then flashes; it also excludes the unused fresh-install image during unpack.

general/overlay/usr/sbin/sysupgrade

load_gokeLoad the CMA allocator without treating full DDR as a carve-out +22/-4

Load the CMA allocator without treating full DDR as a carve-out

• Selects xm_osal’s CMA allocator when specified by bootargs and retains xmedia for existing bootargs. Limits the mem= override to carve-out mode and schedules CMA bootargs for systems without an allocator setting.

general/package/goke-osdrv-gk7205v500/files/script/load_goke

set_allocatorSwitch gk7205v500 bootargs between CMA and xmedia +50/-0

Switch gk7205v500 bootargs between CMA and xmedia

• Adds a command to rewrite U-Boot bootargs for full-DDR CMA or the legacy carve-out while retaining unrelated boot arguments.

general/package/goke-osdrv-gk7205v500/files/script/set_allocator

rootfs_script.shGenerate the FIT before UBI image assembly +21/-0

Generate the FIT before UBI image assembly

• For boards with a NAND FIT definition, builds fitImage from the kernel zImage and DTB before ubinize consumes it.

general/scripts/rootfs_script.sh

Bug fix (2) +89 / -1
initMount ubiblock overlays as UBIFS +6/-1

Mount ubiblock overlays as UBIFS

• Routes ubiblock-rooted systems to the rootfs_data UBIFS mount instead of the JFFS2 fallback, preventing an unintended overlay erase on boot.

general/overlay/init

0001-gk7205v500-build-the-CMA-allocator-into-osal.patchBuild the gk7205v500 OSAL CMA allocator +83/-0

Build the gk7205v500 OSAL CMA allocator

• Adds the CMA allocator object when CMA is enabled and adapts it to the xmedia kernel’s CMA zone API. Removes a duplicate allocator size definition.

general/package/hisilicon-opensdk/0001-gk7205v500-build-the-CMA-allocator-into-osal.patch

Tests (1) +258 / -7
test_sysupgrade.shCover both UBI upgrade layouts and the PID 1 hand-off +258/-7

Cover both UBI upgrade layouts and the PID 1 hand-off

• Adds UBI and UBIFS fixtures and checks layout selection, image refusals, hand-off staging, write order, overlay truncation, package selection, and exclusion of the fresh-install image. Extends write-status invariants to ubiupdatevol.

.github/scripts/test_sysupgrade.sh

Other (5) +102 / -3
gk7205v500.generic.configEnable CMA and movable media memory in the kernel +21/-2

Enable CMA and movable media memory in the kernel

• Enables CMA, DMA CMA, shared CMA memory, compaction, and migration for the gk7205v500 kernel.

br-ext-chip-goke/board/gk7205v500/gk7205v500.generic.config

nand-fit.itsDefine the hashed NAND FIT kernel +49/-0

Define the hashed NAND FIT kernel

• Defines a bootable ARM FIT containing the zImage and board DTB, each with CRC32 and SHA-1 hashes.

br-ext-chip-goke/board/gk7205v500/nand-fit.its

ubinize-nand.cfgDefine kernel, rootfs, and overlay UBI volumes +30/-0

Define kernel, rootfs, and overlay UBI volumes

• Creates separate FIT kernel, UBIFS rootfs, and autoresizing rootfs_data volumes for the NAND installation image.

br-ext-chip-goke/board/gk7205v500/ubinize-nand.cfg

gk7205v500_ultimate_defconfigSelect the board-specific NAND volume layout +1/-1

Select the board-specific NAND volume layout

• Points the gk7205v500 ultimate UBI build at its new ubinize configuration.

br-ext-chip-goke/configs/gk7205v500_ultimate_defconfig

goke-osdrv-gk7205v500.mkInstall the allocator-switching command +1/-0

Install the allocator-switching command

• Installs set_allocator in the gk7205v500 target image alongside the existing loader scripts.

general/package/goke-osdrv-gk7205v500/goke-osdrv-gk7205v500.mk

@widgetii

widgetii commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

The hisilicon-opensdk CMA patch carried here is now upstream as OpenIPC/openhisilicon#236 (same diff, against main = ecbc855). Once that merges, the patch can be dropped in favour of a hisilicon-opensdk bump.

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

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

Copy link
Copy Markdown

Code Review by Qodo

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

Grey Divider


Action required

1. Other OpenSDK users miss the CMA fix ⊘ Outdated
Description
The new hisilicon-opensdk CMA patch changes code fetched from OpenIPC/openhisilicon without
naming an upstream pull request or marking the patch for removal at the next version bump. Until the
fix is submitted upstream, other consumers do not receive it, and a future
HISILICON_OPENSDK_VERSION bump can silently drop or conflict with the local fix.
Code

general/package/hisilicon-opensdk/0001-gk7205v500-build-the-CMA-allocator-into-osal.patch[R1-2]

+From: Dmitry Ilyin <d.ilyin@openipc.org>
+Subject: [PATCH] gk7205v500: build the CMA allocator into osal
Evidence
The package fetches OpenIPC/openhisilicon at a pinned SHA, while the new CMA patch header contains
no upstream pull-request reference. The PR description says the change belongs upstream and will
later be replaced by a version bump, but it also names no pull request for the fix.

Rule 1: A patch against an OpenIPC package is a bridge, not a substitute
general/package/hisilicon-opensdk/hisilicon-opensdk.mk[7-8]
general/package/hisilicon-opensdk/0001-gk7205v500-build-the-CMA-allocator-into-osal.patch[1-12]

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

## Issue description
The local CMA patch targets OpenIPC-owned code but has no upstream pull request or tracking information tying it to the fix that should replace it.
## Fix Focus Areas
- general/package/hisilicon-opensdk/0001-gk7205v500-build-the-CMA-allocator-into-osal.patch[1-12]
## Recommended Fix
Open a pull request for the CMA fix against `OpenIPC/openhisilicon` and cite it in this PR and the patch header. Mark the local patch as temporary and state that it should be dropped at the next `HISILICON_OPENSDK_VERSION` bump that incorporates the upstream change.

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


2. NAND firmware builds fail at packaging 🐞 Bug ≡ Correctness
Description
repack checks rootfs.ubi against 16 MiB even though ubinize-nand.cfg reserves at least 38 MiB
across its three volumes. Every gk7205v500 ultimate build using this layout exceeds the new check
before its NAND archive can be produced.
Code

Makefile[203]

+	@$(call CHECK_SIZE,rootfs.ubi,16384)
Evidence
The new configuration reserves 4 MiB, 32 MiB, and 2 MiB for the kernel, rootfs, and data volumes.
CHECK_SIZE exits when the generated UBI file exceeds the new 16 MiB limit.

br-ext-chip-goke/board/gk7205v500/ubinize-nand.cfg[5-30]
Makefile[196-204]
Makefile[297-309]

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

## Issue description
The NAND FIT repack rejects the UBI image created by its own volume configuration.
## Fix Focus Areas
- Makefile[196-204]
- br-ext-chip-goke/board/gk7205v500/ubinize-nand.cfg[5-30]
## Recommended Fix
Set the rootfs.ubi packaging limit from the actual NAND layout and available NAND capacity, keeping the per-volume checks separate. Verify that a gk7205v500 ultimate repack completes.

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


3. Some cameras lose video after the CMA switch 🐞 Bug ≡ Correctness
Description
insert_osal calls check_allocator, which defaults an unnamed allocator to cma by rewriting the
boot arguments, even on gk7201v200_lite, whose kernel has CMA disabled. On the next boot, Linux
receives the DDR previously reserved for xmedia and insert_osal requests mmz_allocator=cma, but
neither a CMA zone nor the OSAL CMA allocator is available to the media stack.
Code

general/package/goke-osdrv-gk7205v500/files/script/load_goke[R74-76]

+check_allocator() {
+	grep -q mmz_allocator /proc/cmdline || set_allocator cma
+}
Evidence
The gk7201v200 defconfig selects the shared gk7205v500 driver package and a kernel configuration
with CMA disabled. The loader rewrites boot arguments to select CMA whenever no allocator is named,
regardless of board, while the SDK patch builds the OSAL CMA allocator only when CONFIG_CMA=y;
together, these show why the next boot selects an allocator that this board cannot use.

br-ext-chip-goke/configs/gk7201v200_lite_defconfig[24-52]
br-ext-chip-goke/board/gk7205v500/gk7201v200.generic.config[492-492]
general/package/goke-osdrv-gk7205v500/goke-osdrv-gk7205v500.mk[117-118]
general/package/hisilicon-opensdk/0001-gk7205v500-build-the-CMA-allocator-into-osal.patch[19-23]
br-ext-chip-goke/configs/gk7201v200_lite_defconfig[20-24]
br-ext-chip-goke/configs/gk7201v200_lite_defconfig[43-53]
general/package/goke-osdrv-gk7205v500/files/script/load_goke[74-85]

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

## Issue description
The shared Goke loader migrates boards with no named allocator to CMA boot arguments even when their kernel and OSAL do not support CMA, as on gk7201v200. Preserve the xmedia carve-out on unsupported boards.
## Fix Focus Areas
- general/package/goke-osdrv-gk7205v500/files/script/load_goke[70-87]
- general/package/goke-osdrv-gk7205v500/files/script/set_allocator[32-43]
## Recommended Fix
In `check_allocator`, call `set_allocator cma` automatically only when the running kernel and OSAL support the CMA allocator; checking for `^CmaTotal:` in `/proc/meminfo` is one way to gate on kernel CMA support. Otherwise keep the existing xmedia boot arguments for gk7201v200 and other unsupported configurations. Alternatively, enable CMA in `gk7201v200.generic.config` as well.

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



Remediation recommended

4. Local archives can install a foreign rootfs 🐞 Bug ≡ Correctness
Description
verify_ubifs_rootfs() treats remote_update=1 as proof that a UBIFS image is named for the
current model, without inspecting its SoC. --archive also sets that flag, so an archive containing
a foreign UBIFS image under the expected filename and a matching checksum passes preflight on a
generic NAND profile and reaches the rootfs volume write.
Code

general/overlay/usr/sbin/sysupgrade[R484-485]

+	elif [ "1" = "$remote_update" ]; then
+		echo_c 33 "The image is pinned to '$model' by its artifact name."
Evidence
The archive parser sets remote_update without establishing artifact provenance. The new UBIFS
verifier cannot read the image's SoC and accepts that flag; the subsequent rootfs update writes the
accepted image to the UBI volume.

general/overlay/usr/sbin/sysupgrade[473-489]
general/overlay/usr/sbin/sysupgrade[2384-2392]
general/overlay/usr/sbin/sysupgrade[571-583]

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

## Issue description
A local archive is accepted as a model-pinned UBIFS download solely because it sets remote_update.
## Fix Focus Areas
- general/overlay/usr/sbin/sysupgrade[473-489]
- general/overlay/usr/sbin/sysupgrade[2384-2392]
## Recommended Fix
Distinguish a model-pinned fetched artifact from an arbitrary local archive. Require an independent SoC witness or explicit --force_soc for an archive that cannot provide one, while preserving upgrades from correctly pinned release artifacts.

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


5. Unmount failures leave half-upgrades 🐞 Bug ☼ Reliability
Description
release_old_root() ignores the result of busybox umount -l /mnt and proceeds to the flash phase.
If the old root remains mounted, the kernel volume is written first and the subsequent rootfs
ubiupdatevol fails because its volume is still in use.
Code

general/overlay/usr/sbin/sysupgrade[R1603-1605]

+release_old_root() {
+	busybox umount -l /mnt 2>&3
+	sync
Evidence
The new release function has no status check, and its caller invokes flash_and_reboot regardless.
That function writes the kernel before the rootfs, whose UBI update requires the mounted volume to
have been released.

general/overlay/usr/sbin/sysupgrade[1511-1520]
general/overlay/usr/sbin/sysupgrade[1603-1607]
general/overlay/usr/sbin/sysupgrade[2303-2320]
general/overlay/usr/sbin/sysupgrade[2484-2488]

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

## Issue description
The handed-off flash phase continues after an unsuccessful old-root unmount.
## Fix Focus Areas
- general/overlay/usr/sbin/sysupgrade[1596-1607]
- general/overlay/usr/sbin/sysupgrade[2484-2488]
## Recommended Fix
Check the unmount result and abort the handed-off phase before either volume write if release fails. Test the failure path with a failing umount stub.

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


6. A stale FIT can enter another board's package 🐞 Bug ≡ Correctness
Description
The generic repack branch selects NAND FIT packaging solely because $(TARGET)/images/fitImage
exists, while FIT creation is restricted to boards with a matching nand-fit.its. When a build
reuses the same output directory for another non-Rockchip, non-Sigmastar UBI board, a leftover FIT
selects the wrong repack branch and is copied into that board's NAND archive.
Code

Makefile[196]

+else ifneq ($(wildcard $(TARGET)/images/fitImage),)
Evidence
The Makefile defaults to a reusable output directory and tests only for an existing fitImage. The
post-build script creates that file only for a matching board, while the repack macro copies any
file at that path without checking its origin.

Makefile[1-6]
Makefile[193-204]
Makefile[334-342]
general/scripts/rootfs_script.sh[110-129]

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 image left in the shared output directory can select FIT packaging for a different board.
## Fix Focus Areas
- Makefile[193-204]
- general/scripts/rootfs_script.sh[110-129]
## Recommended Fix
Select the FIT repack branch using the current board's FIT configuration rather than image existence alone, and remove or reject a FIT not generated for the current build.

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


View medium (3)
7. Older ubiblock cameras can never upgrade rootfs 🐞 Bug ☼ Reliability
Description
For ubiblock layouts, need_handoff returns true on every rootfs write, and check_handoff refuses
the run unless the running /etc/inittab has a ::restart:/sbin/init entry. That entry ships only
from this PR. self_update replaces the sysupgrade script but not inittab, so every existing
ubiblock camera is refused on every attempt, where it previously upgraded through the MTD path.
Code

general/overlay/usr/sbin/sysupgrade[R1542-1543]

+	grep -qE '^[^#]*::restart:/sbin/init([[:space:]]|$)' "$INITTAB" 2>&3 ||
+		die "This run must rewrite a mounted UBI volume, and only PID 1 can let go of it: $INITTAB has no '::restart:/sbin/init' entry to hand it off with. Nothing was written."
Evidence
The master copy of sysupgrade is executed on remote runs, the layout detection now covers ubiblock
roots, and the handoff check dies without the new inittab line.

general/overlay/usr/sbin/sysupgrade[1794-1820]
general/overlay/usr/sbin/sysupgrade[1523-1529]
general/overlay/usr/sbin/sysupgrade[2068-2077]

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

## Issue description
On ubiblock cameras running older images, sysupgrade refuses every rootfs upgrade because their inittab has no ::restart: entry. Only the upgrade being refused would ship that entry.
## Fix Focus Areas
- general/overlay/usr/sbin/sysupgrade[1537-1545]
- general/overlay/usr/sbin/sysupgrade[2068-2077]
## Recommended Fix
When the running inittab lacks the `::restart:/sbin/init` entry on a ubiblock layout, either fall back to the previous MTD/gluebi write path (clear ubi_layout) or add the entry and reload init with `kill -HUP 1` before the handoff. Do not die permanently.

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


8. A bad overlay volume stops ubiblock boots 🐞 Bug ☼ Reliability
Description
Command lines with root=/dev/ubiblock now go to mount -t ubifs ubi0:rootfs_data /overlay, which
has no fallback. The jffs2 branch these cameras used before fell back to tmpfs. If the volume holds
jffs2 data or is missing, the overlayfs mount fails and init exits, so PID 1 dies and the kernel
panics on every boot.
Code

general/overlay/init[R91-92]

+	if grep -q ubifs /proc/cmdline || grep -qE 'root=/dev/ubiblock' /proc/cmdline; then
mount -t ubifs ubi0:rootfs_data /overlay
Evidence
The new branch has no || fallback, and a failed overlay mount leads straight to exit 1 in init.

general/overlay/init[91-111]
general/overlay/init[125-138]

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

## Issue description
When the UBIFS overlay mount fails, init has nowhere to put the overlay and exits as PID 1.
## Fix Focus Areas
- general/overlay/init[91-92]
## Recommended Fix
Use `mount -t ubifs ubi0:rootfs_data /overlay || mount -t tmpfs tmpfs /overlay || { echo "Cannot mount overlay."; exit 1; }`, mirroring the jffs2 branch.

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


9. Cameras without totalmem drop to 64 MiB ⊘ Outdated
Description
set_allocator cma writes mem=${totalmem:-64M} and sizes the MMZ from the same fallback.
totalmem is set only by u-boot-xmedia, and vendor-bootloader cameras such as gk7205v510 boot
mem=70M. On those cameras the automatic first-boot rewrite saves a 64M memory limit into the U-Boot
env.
Code

general/package/goke-osdrv-gk7205v500/files/script/set_allocator[37]

+		newbootargs="mem=${totalmem:-64M} ${kept}mmz_allocator=cma mmz=${mmz} ${extras}"
Evidence
The 64M default is applied silently on the automatic path, and load_goke itself documents a mem=70M
vendor boot on gk7205v510.

general/package/goke-osdrv-gk7205v500/files/script/set_allocator[19-37]
general/package/goke-osdrv-gk7205v500/files/script/load_goke[23-25]

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

## Issue description
When U-Boot has no totalmem variable, the CMA rewrite falls back to a hard-coded 64M and saves it in the env.
## Fix Focus Areas
- general/package/goke-osdrv-gk7205v500/files/script/set_allocator[23-37]
- general/package/goke-osdrv-gk7205v500/files/script/load_goke[74-76]
## Recommended Fix
If `fw_printenv -n totalmem` is empty, exit without rewriting. Have check_allocator skip the automatic switch in that case.

ⓘ 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 copy the agent prompt from any finding and feed it to your IDE agent

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread Makefile
Comment thread general/overlay/usr/sbin/sysupgrade Outdated
Comment thread general/overlay/usr/sbin/sysupgrade
Comment thread Makefile Outdated
Comment thread general/package/goke-osdrv-gk7205v500/files/script/load_goke
Comment thread general/overlay/usr/sbin/sysupgrade Outdated
Comment thread general/overlay/init Outdated
Comment thread general/package/goke-osdrv-gk7205v500/files/script/set_allocator Outdated
The gk7205v500 family ran with mem=${osmem} (32M) and an xmedia
carve-out for the MMZ, so Linux saw a quarter of a V510's 128 MiB. That
is the wrong configuration for this SoC. On gk7205v200 the MMZ is a CMA
zone inside Linux's memory; this does the same for gk7205v500.

- Kernel: CMA, DMA_CMA, CMA_MEM_SHARED, plus COMPACTION and MIGRATION.
  The xmedia kernel reserves the zone named by mmz= on the command line
  (drivers/xmedia/cma) and, with CMA_MEM_SHARED, lends it to movable
  pages while the media stack does not need it.

- load_goke:
  - A command line that names no allocator is rewritten for the next
    boot:
    mem=${totalmem} ... mmz_allocator=cma mmz=anonymous,0,<osmem>,<rest>
    Every other bootargs token is kept (#2281). totalmem is the DDR size
    u-boot-xmedia writes into the env.
  - xm_osal then loads with mmz_allocator=cma mmz=$MMZ.
  - mmz_allocator=xmedia in bootargs keeps the carve-out.
  - The "os_mem from mem=" override (for vendor bootloaders passing
    mem=70M) now applies to the carve-out only. Under CMA, mem= is the
    whole DDR, and the override tripped load_goke's own
    "os_mem over total_mem" guard, so no module loaded.

- hisilicon-opensdk is bumped to dfc3a81 (OpenIPC/openhisilicon#236). The
  gk7205v500 osal now builds its CMA allocator against the xmedia
  kernel's API, honours the caller's alignment, and refuses to load with
  no usable zone. Both variants take every xm_*.ko from opensdk, so all
  are rebuilt against this kernel.

Verified on a GK7205V510 (128 MiB DDR):
- First boot after the change, still on mem=32M with the carve-out:
  29 modules, no oops, and bootargs rewritten.
- Next boot: "cma: Reserved 96 MiB at 0x42000000", "cmz zone phys
  0x42000000, nbytes 0x6000000". MemTotal is 125840 kB with ~97 MB
  available, against 28612 kB total and ~15 MB available before.
  CmaFree falls by the ~15 MB the media stack allocates.
- majestic reports "HiSilicon SDK started".
A squashfs root on ubiblock (root=/dev/ubiblockX_Y) names no "ubifs" on
the command line, so init took the jffs2 branch. That branch looks
rootfs_data up in /proc/mtd, and gluebi publishes the UBI volume there.
jffs2 then fails to mount on the UBIFS it holds ("Magic bitmask not
found"), and init runs flash_eraseall on it. Every boot erased the
overlay, and the camera's claim with it.

A ubiblock root now mounts ubi0:rootfs_data as UBIFS, as a UBIFS root
does. A squashfs reached through gluebi's mtdblock (root=/dev/mtdblockN,
sigmastar) does not match and keeps the jffs2 branch.

Verified on a GK7205V510 with root=/dev/ubiblock0_1 ubi.block=0,1: the
overlay is ubi0:rootfs_data (ubifs, rw) and the claim survives reboots.
u-boot-xmedia's NAND env reads the UBI volume `kernel`, but the
gk7205v500 NAND image had no such volume: only UBIFS `rootfs` and
`rootfs_data`. A release nand-ultimate image therefore did not boot on
that U-Boot (#2524).

- The NAND image gains a `kernel` volume holding a FIT
  (board/gk7205v500/nand-fit.its): the zImage and xm720xxx-demb.dtb,
  each with crc32 + sha1 hashes. U-Boot refuses a kernel NAND has
  corrupted instead of booting it.
- board/gk7205v500/ubinize-nand.cfg: kernel 4 MiB, rootfs 32 MiB (UBIFS),
  rootfs_data autoresize.
- rootfs_script.sh builds the FIT for any board shipping a nand-fit.its,
  from the kernel tree. ubinize runs before post-image, so post-build is
  the last place it can happen.
- The kernel config is unchanged. The NOR image still boots the uImage
  with its appended DTB, and a plain zImage carries none.
- The -nand- package carries fitImage and rootfs.ubifs, the two images
  sysupgrade writes into those volumes, plus rootfs.ubi for a fresh
  install. Each is size-checked against its volume.

Needs u-boot-xmedia with FIT support for gk7205v500 NAND
(OpenIPC/u-boot-xmedia, "xm720xxx: NAND boots a hashed FIT kernel from
the UBI kernel volume").
sysupgrade addressed flash by MTD partition name. On a NAND camera whose
kernel and rootfs are UBI volumes, `kernel`, `rootfs` and `rootfs_data`
named nothing, or gluebi's view of a volume that is in use, so -k, -r and
-n could not work. This supports both UBI layouts:

  ubifs     kernel = FIT, rootfs = UBIFS (root=ubi0:rootfs). Installs the
            -nand- package: fitImage.<soc> + rootfs.ubifs.<soc>.
  ubiblock  kernel = uImage, rootfs = squashfs through ubiblock
            (root=/dev/ubiblockX_Y). Its volumes hold the NOR artifacts
            verbatim, so it keeps the NOR package.

Everything else -- NOR, a raw NAND kernel partition, a squashfs on
gluebi's mtdblock -- takes the MTD path as before.

Writing:
- Volumes are written with ubiupdatevol, which also trims the 0xFF tail
  of every LEB (#2519).
- UBI_IOCVOLUP takes the volume exclusively (get_exclusive() in
  drivers/mtd/ubi/cdev.c), and the rootfs volume is held open on both
  layouts:
  - UBIFS opens its volume even for a read-only mount;
  - ubiblock holds a reader.
  - Measured on a ubiblock root, from inside the existing ramfs pivot:
    "ubiupdatevol: UBI_IOCVOLUP: Resource busy".
- The pivot cannot help. init's overlay root is the old root, and PID 1
  runs from it.
- So a rootfs write, or -n on a mounted UBIFS overlay, hands PID 1 off
  first, as OpenWrt does with procd/upgraded:
  - inittab gains ::restart:/sbin/init.
  - sysupgrade stages a RAM root whose /sbin/init is its flash phase,
    saves its state there (init execs it with init's environment, not
    ours), pivot_roots (which moves PID 1's root too) and sends SIGQUIT
    to PID 1.
  - busybox init runs its shutdown actions inside the RAM root. umount
    is moved off /bin, so `/bin/umount -a -f` cannot take /tmp and the
    images. init then kills every process and execs the RAM root's
    /sbin/init.
  - As PID 1, the flash phase lazily unmounts the old root, which closes
    the volumes, then writes, then reboots. It never exits: PID 1
    exiting is a panic.
- A kernel-only run never needs the hand-off: the kernel volume is not
  mounted.

Refusals, all before anything is written:
- an inittab with no ::restart: entry;
- a rootfs format the command line will not mount (squashfs on a UBIFS
  root, or the reverse);
- a UBIFS image made for other LEBs than the volume's;
- an image larger than its volume (reserved_ebs * usable_eb_size).

A UBIFS rootfs cannot be loop-mounted, so its SoC rests on the evidence
an unmountable squashfs's does, and its whole verdict is reached before
the pivot.

Unpacking:
- A UBIFS package also holds rootfs.ubi, which is never written here.
  tar leaves it, and its checksum, in the archive: /tmp is RAM.
- The RAM check sizes what is kept. That is about half of the unpacked
  total, but 65% of the packed size measured on the gk7205v500 image:
  UBIFS's 0xFF LEB padding costs gzip almost nothing.

Verified on a GK7205V510 (GD5F1GM7 NAND, 128 MiB DDR, CMA), each run
through the full sysupgrade over HTTP:
- ubifs: --url=...-nand-ultimate.tgz. Hand-off, "Flashing from RAM
  (pid 1)", FIT kernel and UBIFS rootfs written, reboot. U-Boot reports
  "Verifying Hash Integrity ... crc32+ sha1+ OK", the new build boots,
  and the overlay and claim are preserved.
- ubiblock: --url=...-nor-ultimate.tgz. Hand-off, uImage and squashfs
  written, new build boots, overlay and claim preserved.
- -n on the UBIFS overlay: hand-off, rootfs_data erased, and the next
  boot says "default file-system created".
- No ECC, CRC or oops in dmesg after any of them.
@widgetii
widgetii force-pushed the nand/ubi-fit-sysupgrade branch from ba56981 to ad09c41 Compare October 3, 2026 19:01
- load_goke switches to CMA only where the kernel has it
  (/proc/meminfo has CmaTotal). The script also loads gk7201v200, whose
  kernel has no CMA, and it would have lost its MMZ.

- The NAND FIT is described as "OpenIPC <soc>", stamped from
  OPENIPC_SOC_MODEL at build time.
  - sysupgrade reads that as the SoC witness for the UBIFS rootfs beside
    it (fit_soc), and checks it on the kernel write too.
  - A local archive no longer counts as pinned by its file names: a UBIFS
    rootfs without a FIT naming its SoC needs --force_soc.

- Stage 2 refuses to write anything when the old root cannot be
  detached, instead of putting the kernel down and then failing on the
  rootfs volume.

- A ubiblock camera whose inittab predates ::restart: is written through
  gluebi's mtd, as before, rather than refused. Without gluebi it is
  refused, with nothing written.

- init falls back to a tmpfs overlay when rootfs_data will not mount as
  UBIFS, as its jffs2 branch does, instead of PID 1 exiting.

- Repack picks the FIT NAND package by the board's nand-fit.its, not by
  whatever fitImage a reused output directory holds. rootfs_script.sh
  also drops a stale one before building.

test_sysupgrade.sh gains the new cases: 246 checks, green against the
tree and the comment-stripped copy.

Verified on a GK7205V510, sysupgrade --url=...-nand-ultimate.tgz:
"SoC from the FIT kernel beside it: gk7205v500", "SoC OK", PID 1
hand-off, FIT and UBIFS written, the new build boots, the overlay is
kept, and there is no ECC/CRC/oops.
@widgetii

widgetii commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

Review addressed in de9a4d1:

  • 2 (rootfs.ubi over 16 MiB): not a bug. ubinize writes only the LEBs each volume's image fills, not its vol_size. The gk7205v500 build produces a 15104 KB rootfs.ubi and passes this check.
  • 3 (gk7201v200 switched to CMA): fixed. load_goke now switches only when /proc/meminfo has CmaTotal.
  • 4 (local archive taken as pinned): fixed. The NAND FIT is now described as OpenIPC <soc>, and sysupgrade checks it as the UBIFS rootfs's SoC witness. An archive without one needs --force_soc.
  • 5 (umount failure, half upgrade): fixed. Stage 2 refuses before the first write.
  • 6 (stale FIT picks the repack): fixed. The repack keys on the board's nand-fit.its, and a stale fitImage is removed.
  • 7 (old ubiblock cameras refused forever): fixed. Without ::restart:, sysupgrade writes through gluebi as before; without gluebi it refuses with nothing written.
  • 8 (bad overlay volume kills PID 1): fixed. init falls back to a tmpfs overlay.

test_sysupgrade.sh now has 246 checks. Re-verified on the V510 with a real --url NAND sysupgrade: FIT SoC witness gk7205v500, SoC OK, hand-off, new build booted, no errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gk7205v500 NAND: u-boot-xmedia default env expects a UBI kernel volume that nand-ultimate rootfs.ubi does not have

1 participant