From 7d8ff90fd78187dadd232fee2bf8761fff1c1dd1 Mon Sep 17 00:00:00 2001 From: AI Dev Date: Sun, 20 Sep 2026 05:16:32 +0000 Subject: [PATCH 1/2] ci: stop assembling the two NOR images their u-boot has no room for The bounds checks #2448 added ran for the first time on 2026-09-19 and refused six images: hi3516cv6xx ultimate on all four DDR binnings, and hi3519dv500 ultimate on both. That is not a regression #2448 introduced -- it is the table disagreement the published images already carried, now reported instead of shipped -- but it leaves the job red on every run, and re-running against a fresh nightly does not clear it. That run assembled from nightly-20260918-49908b5, because the build had failed and the manifest never advanced, so cv6xx reported a FIT overflow from a blob predating #2447's kernel trim. Measured against the current nightly with create_hisi's own arithmetic, the error changes but does not go away: hi3516cv6xx_lite FIT 2048/2048 ok rootfs 5088/5120 ok hi3516cv6xx_ultimate FIT 2048/2048 ok rootfs 7096/5120 over by 1976 KiB hi3519dv500_ultimate FIT 5632/6144 ok rootfs 8820/8192 over by 628 KiB The cause is that there is one boot binary per DDR binning, not one per part size, and its compiled-in mtdparts is the same on an 8 MiB part and a 16 MiB one. Decompressing the gzip member inside the shipped u-boots (offset 40128 for cv610, 84768 for hi3519dv500) gives: cv610/cv608 256k(boot),64k(env),2048k(kernel),5120k(rootfs),7168k@0x50000(firmware) hi3519dv500 512k(boot),256k(env),6144k(kernel),8192k(rootfs),14336k@0xC0000(firmware) The cv6xx ultimate blob is 9152 KiB and the dv500 one 14464 KiB -- each larger than the whole firmware partition, never mind the rootfs slot inside it. FLASH_SIZE="16" buys them nothing, because the rest of the chip is rootfs_data. No trim closes a 1976 KiB gap, so until a u-boot ships whose table matches a 16 MiB part there is nothing to assemble. So emit cv6xx lite only, and drop the dv500 loop, which has no lite variant to fall back on. Both comments carry the partition numbers so restoring a loop is a two-line change. #2447 fits both cv6xx lite slots exactly (2048 in 2048, 5088 in 5120) and that image assembles and boots today. The .tgz for both variants still publishes from the build job, so sysupgrade is unaffected -- it splits the blob at the FIT boundary and writes each half to its own partition, and refuses an oversized half rather than mis-landing it. --- .github/workflows/image.yml | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml index 86d4a8277f..ace495569b 100644 --- a/.github/workflows/image.yml +++ b/.github/workflows/image.yml @@ -141,7 +141,6 @@ jobs: hisi_layout() { case "$1" in hi3516cv6xx) boot_kib=256 kern_kib=2048 fw_kib=7168 ;; - hi3519dv500) boot_kib=512 kern_kib=6144 fw_kib=14336 ;; *) echo "::error::create_hisi: no NOR layout known for $1"; return 1 ;; esac } @@ -261,8 +260,18 @@ jobs: # reached, nothing would publish for anyone. Collect instead: every # target gets its turn, what did assemble ships (Upload runs on # failure too), and the step still goes red so the refusal is seen. + # lite only. The table above is what the shipped u-boot declares, + # and it is the same table on an 8 MiB part and a 16 MiB one -- + # there is one boot binary per DDR binning, not one per part size. + # So the firmware partition is 7168 KiB either way, and the cv6xx + # ultimate blob is 9152 KiB: it does not fit the partition at all, + # let alone the 5120 KiB rootfs slot inside it. FLASH_SIZE="16" + # buys it nothing, because the rest of the chip is rootfs_data. + # #2448 added the bounds checks that report this; it is not a + # regression they introduced. Re-add ultimate here when a u-boot + # ships whose mtdparts matches a 16 MiB part -- tracked in #2460. hisi_failed= - for variant in lite ultimate; do + for variant in lite; do case $variant in lite) nor=8192 ;; *) nor=16384 ;; esac create_hisi boot-hi3516cv610-10b-nor.bin hi3516cv6xx "$variant" hi3516cv610-ddr2-64m 320 "$nor" || hisi_failed=1 create_hisi boot-hi3516cv610-20s-nor.bin hi3516cv6xx "$variant" hi3516cv610-ddr3-128m 320 "$nor" || hisi_failed=1 @@ -270,15 +279,14 @@ jobs: create_hisi boot-hi3516cv608-nor.bin hi3516cv6xx "$variant" hi3516cv608 320 "$nor" || hisi_failed=1 done - # HiSilicon Hi3519DV500 (aarch64 V5). Same scheme: a single shared - # kernel+rootfs blob (firmware.bin.hi3519dv500) plus a per-binning - # u-boot whose baked DDR reg table differs by board layout — dmeb - # (6-layer) and dmebpro (4-layer flyby), both DDR4-2666 2 GB. NOR - # layout (16 MiB): u-boot @0, env @0x80000, firmware @0xC0000 = 768 KiB. - for variant in ultimate; do - create_hisi boot-hi3519dv500-dmeb-nor.bin hi3519dv500 "$variant" hi3519dv500-dmeb 768 || hisi_failed=1 - create_hisi boot-hi3519dv500-dmebpro-nor.bin hi3519dv500 "$variant" hi3519dv500-dmebpro 768 || hisi_failed=1 - done + # HiSilicon Hi3519DV500 (aarch64 V5) is not assembled here for the + # same reason, and it has no lite variant to fall back on. Its + # u-boot (dmeb 6-layer and dmebpro 4-layer flyby, both DDR4-2666 + # 2 GB) declares 512k(boot),256k(env),6144k(kernel),8192k(rootfs), + # 14336k@0xC0000(firmware); the ultimate blob is 14464 KiB with an + # 8820 KiB rootfs, so it overruns both the rootfs slot and the + # firmware partition. Restore the loop with those numbers in + # hisi_layout once a u-boot exists that declares room for it (#2460). if [ -n "$hisi_failed" ]; then echo "::error::one or more HiSilicon NOR images were refused (see above); the rest were assembled and will still be uploaded" From 9f2aa5a5a39bf2671aa436c577c48ab62787df09 Mon Sep 17 00:00:00 2001 From: AI Dev Date: Sun, 20 Sep 2026 06:11:43 +0000 Subject: [PATCH 2/2] ci: withdraw the ultimate NOR images the release still offers image is a fixed tag and Upload only adds or replaces the files a run produced, so dropping a target from the assembly loops leaves whatever it published last sitting on the release for good. Six such assets were still downloadable, all dated 2026-09-18: the four hi3516cv610/cv608 ultimate images and both hi3519dv500 ones. They are not merely stale. They were assembled before #2448 taught create_hisi to split the blob at the FIT boundary and measure each half against the partition it goes into, so they carry the layout that PR replaced -- a FIT running past the end of the kernel slot and a rootfs written over rootfs_data. Withdrawing the images from the loops without withdrawing them from the release would have left exactly the files this change exists to stop shipping. Delete them by name before Upload, tolerating an asset that is already absent so the step is idempotent and never fails a run. Drop a name from the list when its loop comes back (#2460). --- .github/workflows/image.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml index ace495569b..3583529657 100644 --- a/.github/workflows/image.yml +++ b/.github/workflows/image.yml @@ -300,6 +300,34 @@ jobs: # cancelled run leaves a bootloader on an otherwise blank part. Uploading # that publishes an unflashable image indistinguishable from a finished # one. The ${{ }} is load-bearing: a bare `!` starts a YAML tag. + # `image` is a fixed tag and Upload only adds or replaces the files this + # run produced, so an asset we stop assembling would sit on the release + # for good. These six are exactly that: published before #2448 taught + # create_hisi to measure each half against the partition it goes into, + # and mis-laid by the arithmetic it replaced -- a FIT past the end of the + # kernel slot, a rootfs written over rootfs_data. Withdrawing them by + # name, tolerating absence, keeps the release from offering an image this + # workflow no longer builds. Drop a name from the list when its loop + # comes back (#2460). + - name: Withdraw images this workflow no longer assembles + if: ${{ !cancelled() }} + env: + GH_TOKEN: ${{ github.token }} + run: | + for asset in openipc-hi3516cv610-ddr2-64m-nor-ultimate.bin \ + openipc-hi3516cv610-ddr3-128m-nor-ultimate.bin \ + openipc-hi3516cv610-ddr3-512m-nor-ultimate.bin \ + openipc-hi3516cv608-nor-ultimate.bin \ + openipc-hi3519dv500-dmeb-nor-ultimate.bin \ + openipc-hi3519dv500-dmebpro-nor-ultimate.bin; do + if gh release delete-asset image "$asset" --yes \ + --repo "$GITHUB_REPOSITORY" 2>/dev/null; then + echo "withdrawn: $asset" + else + echo "absent: $asset" + fi + done + - name: Upload if: ${{ !cancelled() }} uses: softprops/action-gh-release@v2