realtek: Introduce Plasma Cloud sysupgrade helper

Plasma Cloud devices use a dual-firmware regions/slots boot mechanism. On
APs, the u-boot is "intelligent" and checks the NOR/NAND partitions (kernel
+ rootfs) for corruption via "datachk". If validation fails, the bootloader
automatically switches to the fallback partition.

On Realtek-based switches, this "datachk" helper is not available.
However, the bootloader still supports two firmware regions/slots.

When flashing a new image, the "inactive" partition is written instead of
overwriting the active one. If no "inactive" partition exists but
"firmware1" is present, the bootloader always treats "firmware1" as
fallback. Only after a successful flash is the `u-boot-env` updated to
select the newly written partition.

On reboot, the bootloader loads the kernel from the new partition and
passes `mtdparts` information as the kernel cmdline. The Plasma Cloud
switch device tree does not override this with a `bootargs` property, so
the active partition layout is honored from cmdline.

Since offsets, sizes, and names of partitions match between the device tree
and cmdline (except the inactive slot), properties and nodes such as
`nvmem-cells` or `compatible` remain fully usable.

This mechanism also allows switching back to the old firmware slot.  For
example, if `firmware1` is currently active (`/proc/mtd` shows it), it can
be switched to slot 2 using:

    . /lib/upgrade/upgrade_dualboot.sh
    set_boot_part 2
    reboot

Firmware upgrades use standard `sysupgrade` tarballs, chosen for
compatibility with vendor images. In theory, one can switch between vendor
and OpenWrt with:

    sysupgrade -n /tmp/*-squashfs-sysupgrade.bin

Note: configuration files must not be preserved, as they are not compatible
with vanilla OpenWrt.

Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19362
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
Harshal Gohel 2025-07-11 15:58:32 +00:00 committed by Hauke Mehrtens
parent ebb342af44
commit 7812d867b4

View File

@ -0,0 +1,68 @@
set_boot_part() {
local part_num="$1"
local setenv_script="/tmp/fw_env_upgrade"
local board=$(board_name)
case "$board" in
*)
echo "${board} is not supported for dual boot" 1>&2
return 1
;;
esac
# store u-boot env changes
mkdir -p /var/lock
cat $setenv_script
fw_setenv -s $setenv_script || {
echo "failed to update U-Boot environment"
return 1
}
}
platform_do_upgrade_dualboot_plasmacloud() {
local primary_firmware_mtd
local restore_backup
local next_boot_part
local tar_file="$1"
local inactive_mtd
local board_dir
inactive_mtd="$(find_mtd_index $PART_NAME)"
if [ -z "$inactive_mtd" ]; then
# Handle case when u-boot-env is not correctly written and we
# are running from initramfs. Only install it in the "firmware1"
# partition
PART_NAME=firmware1
inactive_mtd="$(find_mtd_index $PART_NAME)"
fi
if [ -z "$inactive_mtd" ]; then
echo "Cannot find \"firmware1\" nor \"${$PART_NAME}\" partition to work with. Abort!" 2>&1
return 1
fi
# identify "inactive" slot id based on the expected partition id
# of the primary ("firmware1") slot
case "$(board_name)" in
*)
echo "failed to detect primary firmware mtd partition for board" 2>&1
return 1
;;
esac
if [ "$inactive_mtd" = "$primary_firmware_mtd" ]; then
next_boot_part="1"
else
next_boot_part="2"
fi
[ -n "$UPGRADE_BACKUP" ] && restore_backup="${MTD_CONFIG_ARGS} -j ${UPGRADE_BACKUP}"
# write selected firmware slot
board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
board_dir=${board_dir%/}
tar -xf $tar_file ${board_dir}/kernel ${board_dir}/root -O | mtd $restore_backup write - $PART_NAME
# update u-boot-env to select new firmware slot
set_boot_part "$next_boot_part"
}