[][OpenWrt Dev][Add support for sd/mmc devices to upgrade firmware on specific partitions]

[Description]
Add support for sd/mmc devices to upgrade firmware on specific partitions
specified by kernel cmdline

[Release-log]
N/A

Change-Id: I6348f3a77a3bd5be37c6f60f6a9bf6193e72f095
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5599885
diff --git a/target/linux/mediatek/base-files/lib/upgrade/mmc.sh b/target/linux/mediatek/base-files/lib/upgrade/mmc.sh
index bd1966c..d975e4a 100644
--- a/target/linux/mediatek/base-files/lib/upgrade/mmc.sh
+++ b/target/linux/mediatek/base-files/lib/upgrade/mmc.sh
@@ -18,6 +18,26 @@
 	fi
 }
 
+block_dev_path() {
+	local dev_path
+
+	case "$1" in
+	/dev/mmcblk*)
+		dev_path="$1"
+		;;
+	PARTLABEL=* | PARTUUID=*)
+		dev_path=$(blkid -t "$1" -o device)
+		[ -z "${dev_path}" -o $? -ne 0 ] && return 1
+		;;
+	*)
+		return 1;
+		;;
+	esac
+
+	echo "${dev_path}"
+	return 0
+}
+
 mmc_upgrade_tar() {
 	local tar_file="$1"
 	local kernel_dev="$2"
@@ -76,25 +96,15 @@
 	return 0
 }
 
-mtk_mmc_do_upgrade() {
+mtk_mmc_do_upgrade_generic() {
 	local tar_file="$1"
 	local board=$(board_name)
 	local kernel_dev=
 	local rootfs_dev=
 	local cmdline_root="$(mtk_get_root)"
 
-	case "$cmdline_root" in
-	/dev/mmcblk*)
-		rootfs_dev=${cmdline_root}
-		;;
-	PARTLABEL=* | PARTUUID=*)
-		rootfs_dev=$(blkid -t "${cmdline_root}" -o device)
-		[ -z "${rootfs_dev}" -o $? -ne 0 ] && return 1
-		;;
-	*)
-		return 1;
-		;;
-	esac
+	rootfs_dev=$(block_dev_path "${cmdline_root}")
+	[ -z "${rootfs_dev}" -o $? -ne 0 ] && return 1
 
 	case "$board" in
 	*)
@@ -117,5 +127,93 @@
 		return 1
 	}
 
+	return 0
+}
+
+mtk_mmc_do_upgrade_dual_boot() {
+	local tar_file="$1"
+	local kernel_dev=
+	local rootfs_dev=
+	local rootfs_data_dev=
+
+	local board_dir=$(tar tf ${tar_file} | grep -m 1 '^sysupgrade-.*/$')
+	board_dir=${board_dir%/}
+
+	kernel_dev=$(cat /sys/module/boot_param/parameters/upgrade_kernel_part 2>/dev/null)
+	[ -z "${kernel_dev}" -o $? -ne 0 ] && return 1
+
+	kernel_dev=$(block_dev_path "${kernel_dev}")
+	[ -z "${kernel_dev}" -o $? -ne 0 ] && return 1
+
+	rootfs_dev=$(cat /sys/module/boot_param/parameters/upgrade_rootfs_part 2>/dev/null)
+	[ -z "${kernel_dev}" -o $? -ne 0 ] && return 1
+
+	rootfs_dev=$(block_dev_path "${rootfs_dev}")
+	[ -z "${rootfs_dev}" -o $? -ne 0 ] && return 1
+
+	local kernel_length=$( (tar xf $tar_file ${board_dir}/kernel -O | wc -c) 2> /dev/null)
+	local rootfs_length=$( (tar xf $tar_file ${board_dir}/root -O | wc -c) 2> /dev/null)
+
+	[ "${kernel_length}" != 0 ] && {
+		tar xf ${tar_file} ${board_dir}/kernel -O >${kernel_dev}
+	}
+
+	[ "${rootfs_length}" != 0 ] && {
+		tar xf ${tar_file} ${board_dir}/root -O >${rootfs_dev}
+	}
+
+	upgrade_image_slot=$(cat /sys/module/boot_param/parameters/upgrade_image_slot 2>/dev/null)
+	[ -n "${upgrade_image_slot}" ] && {
+		v "Set new boot image slot to ${upgrade_image_slot}"
+		# Force the creation of fw_printenv.lock
+		mkdir -p /var/lock
+		touch /var/lock/fw_printenv.lock
+		fw_setenv "dual_boot.current_slot" "${upgrade_image_slot}"
+	}
+
+	rootfs_data_dev=$(cat /sys/module/boot_param/parameters/rootfs_data_part 2>/dev/null)
+	[ -z "${rootfs_data_dev}" -o $? -ne 0 ] && return 0
+
+	rootfs_data_dev=$(block_dev_path "${rootfs_data_dev}")
+	[ -z "${rootfs_data_dev}" -o $? -ne 0 ] && return 1
+
+	local rootfs_data_dev_size=$(blockdev --getsize64 ${rootfs_data_dev})
+	[ $? -ne 0 ] && return 1
+
+	local fstype=ext4
+	local mkfs_arg="-q -F -L rootfs_data"
+	[ "${rootfs_data_dev_size}" -gt "${F2FS_MINSIZE}" ] && {
+		fstype=f2fs
+		mkfs_arg="-q -f -l rootfs_data"
+	}
+
+	v "Format rootfs_data."
+	mkfs.${fstype} ${mkfs_arg} ${rootfs_data_dev}
+	[ $? -ne 0 ] && return 1
+
+	[ -n "$UPGRADE_BACKUP" ] && {
+		mkdir -p /tmp/new_root
+		mount -t ${fstype} ${rootfs_data_dev} /tmp/new_root && {
+			v "Saving config to rootfs_data."
+			mv "$UPGRADE_BACKUP" "/tmp/new_root/$BACKUP_FILE"
+			umount /tmp/new_root
+		}
+	}
+
+	# Cleanup
+	sync
+
 	return 0
 }
+
+mtk_mmc_do_upgrade() {
+	local dual_boot=$(cat /sys/module/boot_param/parameters/dual_boot 2>/dev/null)
+
+	if [ x"${dual_boot}" = xY ]; then
+		mtk_mmc_do_upgrade_dual_boot "$1"
+	else
+		mtk_mmc_do_upgrade_generic "$1"
+	fi
+
+	return $?
+}
diff --git a/target/linux/mediatek/mt7986/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7986/base-files/lib/upgrade/platform.sh
index 4a1573a..0c66f47 100644
--- a/target/linux/mediatek/mt7986/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/mt7986/base-files/lib/upgrade/platform.sh
@@ -1,4 +1,5 @@
-RAMFS_COPY_BIN='mkfs.f2fs blkid blockdev'
+RAMFS_COPY_BIN='mkfs.f2fs blkid blockdev fw_printenv fw_setenv'
+RAMFS_COPY_DATA="/etc/fw_env.config /var/lock/fw_printenv.lock"
 
 platform_do_upgrade() {
 	local board=$(board_name)