base-files: add eMMC sysupgrade support
authorEnrico Mioso <mrkiko.rs@gmail.com>
Wed, 1 Dec 2021 15:17:55 +0000 (16:17 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Thu, 2 Dec 2021 20:42:58 +0000 (20:42 +0000)
Adds generic support for sysupgrading on eMMC-based devices.

Provide function emmc_do_upgrade and emmc_copy_config to be used in
/lib/upgrade/platform.sh instead of redundantly implementing the same
logic over and over again.
Similar to generic sysupgrade on NAND, use environment variables
CI_KERNPART, CI_ROOTPART and newly introduce CI_DATAPART to indicate
GPT partition names to be used. On devices with more than one MMC
block device, CI_ROOTDEV can be used to specify the MMC device for
partition name lookups.

Also allow to select block devices directly using EMMC_KERN_DEV,
EMMC_ROOT_DEV and EMMC_DATA_DEV, as using GPT partition names is not
always an option (e.g. when forced to use MBR).

To easily handle writing kernel and rootfs make use of sysupgrade.tar
format convention which is also already used for generic NAND support.

Signed-off-by: Enrico Mioso <mrkiko.rs@gmail.com>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
CC: Li Zhang <li.zhang@gl-inet.com>
CC: TruongSinh Tran-Nguyen <i@truongsinh.pro>
package/base-files/Makefile
package/base-files/files/lib/upgrade/emmc.sh [new file with mode: 0644]
scripts/target-metadata.pl
target/Config.in

index af5c0e6b004704b4094264bd9228703bb1b8b29b..914f0598ff9c181952f20f769e64d2b1121b6ae2 100644 (file)
@@ -24,6 +24,7 @@ PKG_CONFIG_DEPENDS += \
        CONFIG_SIGNED_PACKAGES CONFIG_TARGET_INIT_PATH CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE \
        CONFIG_NAND_SUPPORT \
        CONFIG_LEGACY_SDCARD_SUPPORT \
+       CONFIG_EMMC_SUPPORT \
        CONFIG_CLEAN_IPKG \
        CONFIG_PER_FEED_REPO \
        $(foreach feed,$(FEEDS_AVAILABLE),CONFIG_FEED_$(feed))
@@ -124,6 +125,12 @@ ifeq ($(CONFIG_NAND_SUPPORT),)
   endef
 endif
 
+ifeq ($(CONFIG_EMMC_SUPPORT),)
+  define Package/base-files/emmc-support
+       rm -f $(1)/lib/upgrade/emmc.sh
+  endef
+endif
+
 ifeq ($(CONFIG_LEGACY_SDCARD_SUPPORT),)
   define Package/base-files/legacy-sdcard-support
        rm -f $(1)/lib/upgrade/legacy-sdcard.sh
@@ -136,6 +143,7 @@ define Package/base-files/install
        $(Package/base-files/install-key)
        $(Package/base-files/nand-support)
        $(Package/base-files/legacy-sdcard-support)
+       $(Package/base-files/emmc-support)
        if [ -d $(GENERIC_PLATFORM_DIR)/base-files/. ]; then \
                $(CP) $(GENERIC_PLATFORM_DIR)/base-files/* $(1)/; \
        fi
diff --git a/package/base-files/files/lib/upgrade/emmc.sh b/package/base-files/files/lib/upgrade/emmc.sh
new file mode 100644 (file)
index 0000000..15fa370
--- /dev/null
@@ -0,0 +1,64 @@
+# Copyright (C) 2021 OpenWrt.org
+#
+
+. /lib/functions.sh
+
+emmc_upgrade_tar() {
+       local tar_file="$1"
+       [ "$CI_KERNPART" -a -z "$EMMC_KERN_DEV" ] && export EMMC_KERN_DEV="$(find_mmc_part $CI_KERNPART $CI_ROOTDEV)"
+       [ "$CI_ROOTPART" -a -z "$EMMC_ROOT_DEV" ] && export EMMC_ROOT_DEV="$(find_mmc_part $CI_ROOTPART $CI_ROOTDEV)"
+       [ "$CI_DATAPART" -a -z "$EMMC_DATA_DEV" ] && export EMMC_DATA_DEV="$(find_mmc_part $CI_DATAPART $CI_ROOTDEV)"
+       local has_kernel
+       local has_rootfs
+       local board_dir=$(tar tf "$tar_file" | grep -m 1 '^sysupgrade-.*/$')
+       board_dir=${board_dir%/}
+
+       tar tf "$tar_file" ${board_dir}/kernel 1>/dev/null 2>/dev/null && has_kernel=1
+       tar tf "$tar_file" ${board_dir}/root 1>/dev/null 2>/dev/null && has_rootfs=1
+
+       [ "$has_kernel" = 1 -a "$EMMC_KERN_DEV" ] &&
+               export EMMC_KERNEL_BLOCKS=$(($(tar xf "$tar_file" ${board_dir}/kernel -O | dd of="$EMMC_KERN_DEV" bs=512 2>&1 | grep "records out" | cut -d' ' -f1)))
+
+       [ "$has_rootfs" = 1 -a "$EMMC_ROOT_DEV" ] &&
+               export EMMC_ROOTFS_BLOCKS=$(($(tar xf "$tar_file" ${board_dir}/root -O | dd of="$EMMC_ROOT_DEV" bs=512 2>&1 | grep "records out" | cut -d' ' -f1)))
+
+       if [ -z "$UPGRADE_BACKUP" ]; then
+               if [ "$EMMC_DATA_DEV" ]; then
+                       dd if=/dev/zero of="$EMMC_DATA_DEV" bs=512 count=8
+               elif [ "$EMMC_ROOTFS_BLOCKS" ]; then
+                       dd if=/dev/zero of="$EMMC_ROOT_DEV" bs=512 seek=$EMMC_ROOTFS_BLOCKS count=8
+               elif [ "$EMMC_KERNEL_BLOCKS" ]; then
+                       dd if=/dev/zero of="$EMMC_KERN_DEV" bs=512 seek=$EMMC_KERNEL_BLOCKS count=8
+               fi
+       fi
+}
+
+emmc_upgrade_fit() {
+       local fit_file="$1"
+       [ "$CI_KERNPART" -a -z "$EMMC_KERN_DEV" ] && export EMMC_KERN_DEV="$(find_mmc_part $CI_KERNPART $CI_ROOTDEV)"
+
+       if [ "$EMMC_KERN_DEV" ]; then
+               export EMMC_KERNEL_BLOCKS=$(($(get_image "$fit_file" | fwtool -i /dev/null -T - | dd of="$EMMC_KERN_DEV" bs=512 2>&1 | grep "records out" | cut -d' ' -f1)))
+
+               [ -z "$UPGRADE_BACKUP" ] && dd if=/dev/zero of="$EMMC_KERN_DEV" bs=512 seek=$EMMC_KERNEL_BLOCKS count=8
+       fi
+}
+
+emmc_copy_config() {
+       if [ "$EMMC_DATA_DEV" ]; then
+               dd if="$UPGRADE_BACKUP" of="$EMMC_DATA_DEV" bs=512
+       elif [ "$EMMC_ROOTFS_BLOCKS" ]; then
+               dd if="$UPGRADE_BACKUP" of="$EMMC_ROOT_DEV" bs=512 seek=$EMMC_ROOTFS_BLOCKS
+       elif [ "$EMMC_KERNEL_BLOCKS" ]; then
+               dd if="$UPGRADE_BACKUP" of="$EMMC_KERN_DEV" bs=512 seek=$EMMC_KERNEL_BLOCKS
+       fi
+}
+
+emmc_do_upgrade() {
+       local file_type=$(identify $1)
+
+       case "$file_type" in
+               "fit")  emmc_upgrade_fit $1;;
+               *)      emmc_upgrade_tar $1;;
+       esac
+}
index 163eb3768bdea294bcc5731a2e17dee031b94174..e1d4ef242b865d8351ae3ad2d159a4e1eefded96 100755 (executable)
@@ -17,6 +17,7 @@ sub target_config_features(@) {
                /^display$/ and $ret .= "\tselect DISPLAY_SUPPORT\n";
                /^dt$/ and $ret .= "\tselect USES_DEVICETREE\n";
                /^dt-overlay$/ and $ret .= "\tselect HAS_DT_OVERLAY_SUPPORT\n";
+               /^emmc$/ and $ret .= "\tselect EMMC_SUPPORT\n";
                /^ext4$/ and $ret .= "\tselect USES_EXT4\n";
                /^fpu$/ and $ret .= "\tselect HAS_FPU\n";
                /^gpio$/ and $ret .= "\tselect GPIO_SUPPORT\n";
index 32242446ee6c49743cc619105d03240a7799a5f2..a6b3351a61886a63544e64cce036e3275c4f2cdf 100644 (file)
@@ -98,6 +98,9 @@ config HAS_MIPS16
 config RFKILL_SUPPORT
        bool
 
+config EMMC_SUPPORT
+       bool
+
 config NAND_SUPPORT
        bool