Report
hi3516cv6xx_ultimate and hi3519dv500_ultimate cannot be assembled into a
full-chip NOR image, because the u-boot they are paired with declares a
firmware partition smaller than the image. Both are excluded from the image
workflow for now; this issue tracks fixing them properly.
What the u-boot declares
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. Read back
out of the shipped binaries (a HiSilicon boot table followed by a gzip member —
offset 40128 for cv610, 84768 for hi3519dv500 — that decompresses to the u-boot
payload):
$ tail -c +40129 boot-hi3516cv610-20s-nor.bin | gzip -dc | strings -n 20 | grep mtdparts=
mtdparts=${mtdids}:256k(boot),64k(env),2048k(kernel),5120k(rootfs),7168k@0x50000(firmware),-(rootfs_data)
$ tail -c +84769 boot-hi3519dv500-dmeb-nor.bin | gzip -dc | strings -n 20 | grep mtdparts=
mtdparts=512k(boot),256k(env),6144k(kernel),8192k(rootfs),14336k@0xC0000(firmware),-(rootfs_data)
Nothing in the firmware tree rewrites mtdparts or kernsize afterwards
(set_allocator only edits the mmz part of bootargs), so the compiled-in
default is what runs.
What the images are
Measured against the current nightly blobs with the arithmetic create_hisi
in .github/workflows/image.yml uses — the FIT's total size is the big-endian
word at byte 4, rounded up to the next 64 KiB; the rootfs length is bytes_used
in the squashfs superblock (little-endian u64 at byte 40), rounded up to 4 KiB:
hi3516cv6xx_lite blob 7168 KiB FIT 2048/2048 ok rootfs 5088/5120 ok
hi3516cv6xx_ultimate blob 9152 KiB FIT 2048/2048 ok rootfs 7096/5120 over by 1976 KiB
hi3519dv500_ultimate blob 14464 KiB FIT 5632/6144 ok rootfs 8820/8192 over by 628 KiB
The cv6xx ultimate blob (9152 KiB) is larger than its entire 7168 KiB firmware
partition, and the dv500 one (14464 KiB) than its 14336 KiB partition.
BR2_OPENIPC_FLASH_SIZE="16" buys neither anything, because the rest of the
chip is rootfs_data. #2447 fixed the cv6xx lite case by trimming the shared
kernel and it now lands exactly on both slots; it could not fix ultimate, whose
rootfs is the half that overflows.
Why it surfaced now
#2448 taught create_hisi to split the blob at the FIT boundary and measure
each half against the partition it goes into, rather than writing the combined
blob verbatim at the firmware offset. The image workflow then ran for the
first time since (every run in between was skipped) and refused six images.
The refusal is correct — the published images already carried this
disagreement, it was simply never checked.
What would fix it
A cv610/cv608 and a hi3519dv500 u-boot whose mtdparts, kernaddr and
kernsize describe a 16 MiB part, published alongside the existing 8 MiB ones
so the assembler can pair the ultimate blob with a table that has room for it.
That is u-boot work and needs the hardware to validate — an image built on a
wrong table boots a truncated kernel or lands the rootfs over rootfs_data,
and the boards it would be tested on have no serial recovery path recorded.
Restoring the images afterwards is a two-line change: re-add ultimate to the
cv6xx loop and the dv500 loop to .github/workflows/image.yml, with the new
numbers in hisi_layout. Both comments in that file carry the current numbers.
Not affected
sysupgrade already does the right thing and is unchanged: do_update_firmware
splits the blob at the FIT boundary and writes each half to its own partition,
and check_combined_fits refuses the write outright when either half is
oversized. So an over-large combined image fails safe over the air — this only
ever mis-landed on a fresh whole-chip flash of the assembled release .bin.
The .tgz for both variants still publishes from the build job.
Report
hi3516cv6xx_ultimateandhi3519dv500_ultimatecannot be assembled into afull-chip NOR image, because the u-boot they are paired with declares a
firmware partition smaller than the image. Both are excluded from the
imageworkflow for now; this issue tracks fixing them properly.
What the u-boot declares
There is one boot binary per DDR binning, not one per part size, and its
compiled-in
mtdpartsis the same on an 8 MiB part and a 16 MiB one. Read backout of the shipped binaries (a HiSilicon boot table followed by a gzip member —
offset 40128 for cv610, 84768 for hi3519dv500 — that decompresses to the u-boot
payload):
Nothing in the firmware tree rewrites
mtdpartsorkernsizeafterwards(
set_allocatoronly edits the mmz part ofbootargs), so the compiled-indefault is what runs.
What the images are
Measured against the current nightly blobs with the arithmetic
create_hisiin
.github/workflows/image.ymluses — the FIT's total size is the big-endianword at byte 4, rounded up to the next 64 KiB; the rootfs length is
bytes_usedin the squashfs superblock (little-endian u64 at byte 40), rounded up to 4 KiB:
The cv6xx ultimate blob (9152 KiB) is larger than its entire 7168 KiB firmware
partition, and the dv500 one (14464 KiB) than its 14336 KiB partition.
BR2_OPENIPC_FLASH_SIZE="16"buys neither anything, because the rest of thechip is
rootfs_data. #2447 fixed the cv6xx lite case by trimming the sharedkernel and it now lands exactly on both slots; it could not fix ultimate, whose
rootfs is the half that overflows.
Why it surfaced now
#2448 taught
create_hisito split the blob at the FIT boundary and measureeach half against the partition it goes into, rather than writing the combined
blob verbatim at the firmware offset. The
imageworkflow then ran for thefirst time since (every run in between was
skipped) and refused six images.The refusal is correct — the published images already carried this
disagreement, it was simply never checked.
What would fix it
A cv610/cv608 and a hi3519dv500 u-boot whose
mtdparts,kernaddrandkernsizedescribe a 16 MiB part, published alongside the existing 8 MiB onesso the assembler can pair the ultimate blob with a table that has room for it.
That is u-boot work and needs the hardware to validate — an image built on a
wrong table boots a truncated kernel or lands the rootfs over
rootfs_data,and the boards it would be tested on have no serial recovery path recorded.
Restoring the images afterwards is a two-line change: re-add
ultimateto thecv6xx loop and the dv500 loop to
.github/workflows/image.yml, with the newnumbers in
hisi_layout. Both comments in that file carry the current numbers.Not affected
sysupgradealready does the right thing and is unchanged:do_update_firmwaresplits the blob at the FIT boundary and writes each half to its own partition,
and
check_combined_fitsrefuses the write outright when either half isoversized. So an over-large combined image fails safe over the air — this only
ever mis-landed on a fresh whole-chip flash of the assembled release
.bin.The
.tgzfor both variants still publishes from the build job.