[OpenWrt-Devel] [RFC] sysupgrade: Cross-flashing NOR/NAND proof of concept

Jeff Kletsky lede at allycomm.com
Tue Jun 11 20:42:08 EDT 2019


From: Jeff Kletsky <git-commits at allycomm.com>

Certain devices can have both NOR- and NAND-resident firmware, such as
the GL.iNet GL-AR300M. These devices can be booted with either firmware.
The GL-AR300M boot loader will automatically fail-over to NOR firmware
after three failed boots, providing end-user benefits when bad flashes
or other "no boot" situations occur.

THIS IS A PROOF OF CONCEPT

The "tricks" are that:

  * The kernel and software for both the NOR- and NAND-resident
    variants need to be able to read/write raw MTD as well as UBI.

  * The existing sysupgrade paths already prevent flashing of a
    NOR-intended image onto a NAND-based device, as well as the other
    way around. As such, even if a approach like this is accepted
    after these board names are "in the wild", sysupgrade will be
    "safe" on "old" builds against future additions to SUPPORTED_DEVICES.

  * The MTD partitioning for both variants need to define both NOR and
    NAND partitioning in a way that:

      * Early init does not try to mount the "wrong" root file system

      * sysupgrade can locate the "other" partitions

    This was accomplished in the commit sequence for the GL-AR300M
    (linked below) by defining the partitions in a common DTSI with a
    "neutered" partition label, prefixing it with nor_ or nand_, then
    setting the label as appropriate within the DTS for the specific
    build.

It can be used with buildable code for the GL.iNet AR300M that is
being prepared for submission and is presently available at

  https://github.com/jeffsf/openwrt/tree/ath79-nand-2019-06-11

or the latest, similarly named branch. Note that the above code has
not implemented SUPPORTED_DEVICES to allow cross-flashing, so that
sysupgrade -F will be required for those cases (at this time).

It intentionally does *not* switch to the flashed partition at this time.

Past removing my comments/notes in the source, I'd be interesting in
finding out if there are cases that I haven't thought of.

Run-tested-on: GL.iNet AR300M

Signed-off-by: Jeff Kletsky <git-commits at allycomm.com>
---
 .../ath79/base-files/lib/upgrade/platform.sh  | 65 +++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/target/linux/ath79/base-files/lib/upgrade/platform.sh b/target/linux/ath79/base-files/lib/upgrade/platform.sh
index b6f720fd0a..110d459b27 100644
--- a/target/linux/ath79/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ath79/base-files/lib/upgrade/platform.sh
@@ -32,6 +32,67 @@ redboot_fis_do_upgrade() {
 	fi
 }
 
+nand_nor_do_upgrade() {
+	local upgrade_file="$1"
+
+	local magic
+	local found_nor_part
+
+	# If here, the metadata check has already passed (or --force)
+	# ath79:nand so far only uses uImage and tar files
+
+	magic=$(get_magic_long "$upgrade_file")
+	case "$magic" in
+
+	"27051956")	#define IH_MAGIC 0x27051956 /* [U-Boot] Image Magic Number */
+
+		found_nor_part="Not yet"
+		for pn in "$PART_NAME" "nor_${PART_NAME}" ; do		# firmware
+
+			if [ "$(find_mtd_index "$pn")" ] ; then
+				PART_NAME="$pn"
+				found_nor_part=''
+				>&2 printf "Running NOR upgrade\n"
+				default_do_upgrade "$upgrade_file"
+			fi
+		done
+		if [ -n "$found_nor_part" ] ; then
+			>&2 printf "ERROR: UPGRADE FAILED: Unable to locate '$PART_NAME' or 'nor_${PART_NAME}'\n"
+			sleep 5
+			exit 1
+		fi
+		;;
+
+
+	*)	# has to be a tar file of some sort
+
+		for pn in "$CI_KERNPART" "nand_${CI_KERNPART}" ; do	# kernel
+
+			if [ "$(find_mtd_index "$pn")" ] ; then
+				CI_KERNPART="$pn"
+				break
+			fi
+		done
+		for pn in "$CI_UBIPART" "nand_${CI_UBIPART}" ; do	# ubi
+
+			if [ "$(find_mtd_index "$pn")" ] ; then
+				CI_UBIPART="$pn"
+				break
+			fi
+		done
+		for pn in "$CI_ROOTPART" "nand_${CI_ROOTPART}" ; do	#rootfs
+
+			if [ "$(find_mtd_index "$pn")" ] ; then
+				CI_ROOTPART="$pn"
+				break
+			fi
+		done
+		>&2 printf "Running NAND upgrade\n"
+		nand_upgrade_tar "$upgrade_file"
+		;;
+	esac
+}
+
 platform_check_image() {
 	return 0
 }
@@ -47,6 +108,10 @@ platform_do_upgrade() {
 	ubnt,routerstation-pro)
 		redboot_fis_do_upgrade "$ARGV" kernel
 		;;
+	glinet,gl-ar300m-nand |\
+	glinet,gl-ar300m-nor)
+		nand_nor_do_upgrade "$ARGV"
+		;;
 	*-nand)
 		nand_do_upgrade "$ARGV"
 		;;
-- 
2.20.1


_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list