Summary
set_allocator rebuilds bootargs from a fixed whitelist of keys and re-saves it with fw_setenv. Any boot argument not in that whitelist is silently dropped — including ubi.mtd, which NAND/UBI variants require to attach ubi0. After set_allocator cma runs (during load_hisilicon/load_goke at boot), the next boot panics:
ubi0: attached mtd3 (name "ubi", size 118 MiB)
ubi0: good PEBs: 944, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 0, internal volumes: 1
VFS: Cannot open root device "ubi0:rootfs" or unknown-block(0,0): error -19
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
(without ubi.mtd=<n> on the cmdline the kernel never attaches UBI, so root=ubi0:rootfs cannot be found).
Affected packages
The same set_allocator script (identical whitelist-rebuild) ships in:
general/package/hisilicon-osdrv-hi3516ev200 (covers hi3516ev300)
general/package/hisilicon-osdrv-hi3516cv6xx
general/package/hisilicon-osdrv-hi3516av100
general/package/hisilicon-osdrv-hi3519dv500
general/package/goke-osdrv-gk7205v200
None of them preserve ubi.mtd, so every NAND/UBI (ubi.mtd=…) variant of these SoCs is affected.
Root cause
general/package/hisilicon-osdrv-hi3516ev200/files/script/set_allocator:
get_env() {
bootargs=$(fw_printenv -n bootargs)
mem=$(... $1=="mem" ...)
console=$(...$1=="console" ...)
panic=$(... $1=="panic" ...)
rootfstype=$(...$1=="rootfstype"...)
root=$(... $1=="root" ...)
init=$(... $1=="init" ...)
mtdparts=$(...$1=="mtdparts" ...)
# ubi.mtd (and anything else) is never captured
}
...
# cma branch
newbootargs="mem=${mem} console=${console} panic=${panic} rootfstype=${rootfstype} root=${root} init=${init} mtdparts=${mtdparts} mmz_allocator=cma mmz=${mmz}"
fw_setenv bootargs ${newbootargs}
get_env() only parses a fixed set of keys and the rebuild emits only those keys + mmz*. ubi.mtd is dropped, so the persisted bootargs can no longer attach UBI.
Reproduction
- Flash the NAND/UBI build, e.g.
openipc.hi3516ev300-nand-ultimate.tgz, with correct bootargs including ubi.mtd=3,2048. First boot works.
- During that boot
load_hisilicon runs set_allocator cma, which rewrites bootargs without ubi.mtd.
- Reboot → kernel panic (UBI never attached).
Observed cmdline after set_allocator (note missing ubi.mtd):
mem=128M console=ttyAMA0,115200 panic=20 rootfstype=ubifs root=ubi0:rootfs init= mtdparts=hinand:1024k(boot),1024k(env),8192k(kernel),-(ubi) mmz_allocator=cma mmz=anonymous,0,0x42000000,96M
Suggested fix
Preserve ubi.mtd (and ideally any other unrecognised args) across the rewrite. Minimal change — capture and re-emit ubi.mtd:
# in get_env()
ubimtd=$(echo ${bootargs} | awk -F '=' '$1=="ubi.mtd"{print $2}' RS=' ')
# when rebuilding (both hisi and cma branches), insert when present:
[ -n "$ubimtd" ] && ubiarg="ubi.mtd=${ubimtd} " || ubiarg=""
newbootargs="mem=${mem} console=${console} panic=${panic} rootfstype=${rootfstype} root=${root} init=${init} ${ubiarg}mtdparts=${mtdparts} mmz_allocator=cma mmz=${mmz}"
A more robust approach would edit only the mem/mmz/mmz_allocator tokens in-place and leave the rest of bootargs untouched, so future additions aren't silently dropped either.
Environment
- Board: Rostelecom IPC8232SWC-WE (hi3516ev300, 128 MiB SPI-NAND W25N01GV)
- Firmware:
openipc.hi3516ev300-nand-ultimate.tgz, OpenIPC master+6a3cde2
- Workaround used:
fw_setenv bootargs '... ubi.mtd=3,2048 ...' after each set_allocator, or don't let set_allocator run — but the real fix is preserving ubi.mtd in the script.
Summary
set_allocatorrebuildsbootargsfrom a fixed whitelist of keys and re-saves it withfw_setenv. Any boot argument not in that whitelist is silently dropped — includingubi.mtd, which NAND/UBI variants require to attachubi0. Afterset_allocator cmaruns (duringload_hisilicon/load_gokeat boot), the next boot panics:(without
ubi.mtd=<n>on the cmdline the kernel never attaches UBI, soroot=ubi0:rootfscannot be found).Affected packages
The same
set_allocatorscript (identical whitelist-rebuild) ships in:general/package/hisilicon-osdrv-hi3516ev200(covers hi3516ev300)general/package/hisilicon-osdrv-hi3516cv6xxgeneral/package/hisilicon-osdrv-hi3516av100general/package/hisilicon-osdrv-hi3519dv500general/package/goke-osdrv-gk7205v200None of them preserve
ubi.mtd, so every NAND/UBI (ubi.mtd=…) variant of these SoCs is affected.Root cause
general/package/hisilicon-osdrv-hi3516ev200/files/script/set_allocator:get_env()only parses a fixed set of keys and the rebuild emits only those keys +mmz*.ubi.mtdis dropped, so the persisted bootargs can no longer attach UBI.Reproduction
openipc.hi3516ev300-nand-ultimate.tgz, with correct bootargs includingubi.mtd=3,2048. First boot works.load_hisiliconrunsset_allocator cma, which rewritesbootargswithoutubi.mtd.Observed cmdline after
set_allocator(note missingubi.mtd):Suggested fix
Preserve
ubi.mtd(and ideally any other unrecognised args) across the rewrite. Minimal change — capture and re-emitubi.mtd:A more robust approach would edit only the
mem/mmz/mmz_allocatortokens in-place and leave the rest ofbootargsuntouched, so future additions aren't silently dropped either.Environment
openipc.hi3516ev300-nand-ultimate.tgz, OpenIPCmaster+6a3cde2fw_setenv bootargs '... ubi.mtd=3,2048 ...'after eachset_allocator, or don't letset_allocatorrun — but the real fix is preservingubi.mtdin the script.