From f9396581fd806c6b93515904f4ecdf369353457d Mon Sep 17 00:00:00 2001 From: David Escalona Date: Fri, 7 Jul 2023 10:57:30 +0200 Subject: [PATCH] meta-digi-dey: swupdate: add firmware update support based on differences for R/O systems Implement a new mechanism to allow users to create update packages based on differences for read-only systems. The update mechanism requires full knowledge of the current software running on the device in order to compute a sensitive patch. For this reason, only systems without user modifications in the rootfs/boot partitions are eligible for this kind of updates. At the moment, only the 'rootfs' partition supports the read-only squashfs file system type, so it is the only partition supporting incremental updates. The 'boot' partition will still be updated but as a full image. This new feature is done making use of the SWUpdate 'rdiff' handler, which applies binary deltas with the functionallity provided by the rsync library. During the update process, the contents of the active 'rootfs' partition are read as the base and written to the inactive 'rootfs' partition applying the delta binary patch on-the-fly. To ensure the delta file is applied using the correct base, the firmware update process verifies the contents of the 'rootfs' base partition before applying the update. The binary delta file is automatically generated by the DEY build system using the resulting 'rootfs' squashfs image as target and the user specified file as source. The file is then packaged with the rest of components in the SWU update image. Users must specify the base source file in their project configuration file using the new variable 'SWUPDATE_RDIFF_ROOTFS_SOURCE_FILE'. Also, 'read-only-rootfs' image feature should be set in the project to generate this new SWU update package. Since a base and a target 'rootfs' partition is required during the update, only 'dualboot' systems can benefit from this new feature. Note: If variable 'SWUPDATE_RDIFF_ROOTFS_SOURCE_FILE' is configured in the project but any of 'SWUPDATE_FILES_LIST' or 'SWUPDATE_FILES_TARGZ_FILE' variables is also set, the build system will prioritize a SWU update package based on files instead of a differences package. https://onedigi.atlassian.net/browse/DEL-8624 Signed-off-by: David Escalona --- .../classes/dey-swupdate-common.bbclass | 32 ++- meta-digi-dey/classes/dey-swupdate.bbclass | 25 +++ .../swu-images/files/image_template_rdiff_mmc | 8 + .../files/image_template_rdiff_nand | 9 + .../files/sw-description-rdiff_template | 49 +++++ .../swu-images/files/update_rdiff.sh | 206 ++++++++++++++++++ meta-digi-dey/recipes-digi/swu-images/swu.inc | 38 +++- 7 files changed, 355 insertions(+), 12 deletions(-) create mode 100644 meta-digi-dey/recipes-digi/swu-images/files/image_template_rdiff_mmc create mode 100644 meta-digi-dey/recipes-digi/swu-images/files/image_template_rdiff_nand create mode 100644 meta-digi-dey/recipes-digi/swu-images/files/sw-description-rdiff_template create mode 100755 meta-digi-dey/recipes-digi/swu-images/files/update_rdiff.sh diff --git a/meta-digi-dey/classes/dey-swupdate-common.bbclass b/meta-digi-dey/classes/dey-swupdate-common.bbclass index ee96e2d97..7e3031d3e 100644 --- a/meta-digi-dey/classes/dey-swupdate-common.bbclass +++ b/meta-digi-dey/classes/dey-swupdate-common.bbclass @@ -48,6 +48,26 @@ def update_based_on_files(d): # Variable that determines if SWU update is based on files or not. SWUPDATE_IS_FILES_UPDATE = "${@update_based_on_files(d)}" +####################################### +###### SWU Update based on RDIFF ###### +####################################### + +# Variable used to generate the 'rootfs' RDIFF file. Do not modify. +SWUPDATE_RDIFF_ROOTFS_DELTA_FILE_NAME = "swupdate-rootfs.rdiff" + +# Initialize variable to provide the base file from which to generate the 'rootfs' RDIFF file. +SWUPDATE_RDIFF_ROOTFS_SOURCE_FILE ?= "" + +# Rdiff image template based on storage type. +SWUPDATE_RDIFF_IMAGE_TEMPLATE_FILE = "${@bb.utils.contains('STORAGE_MEDIA', 'mmc', 'image_template_rdiff_mmc', 'image_template_rdiff_nand', d)}" + +# Checks whether SWU update is based on RDIFF or not. +def update_based_on_rdiff(d): + return str("read-only-rootfs" in d.getVar('IMAGE_FEATURES') and d.getVar('SWUPDATE_IS_FILES_UPDATE') != "true" and d.getVar('SWUPDATE_RDIFF_ROOTFS_SOURCE_FILE') != "").lower() + +# Variable that determines if SWU update is based on RDIFF or not. +SWUPDATE_IS_RDIFF_UPDATE = "${@update_based_on_rdiff(d)}" + ####################################### ##### SWU Update based on images ###### ####################################### @@ -57,7 +77,7 @@ SWUPDATE_IMAGES_IMAGE_TEMPLATE_FILE = "${@bb.utils.contains('STORAGE_MEDIA', 'mm # Checks whether SWU update is based on images or not. def update_based_on_images(d): - return str(d.getVar('SWUPDATE_IS_FILES_UPDATE') != "true").lower() + return str(d.getVar('SWUPDATE_IS_FILES_UPDATE') != "true" and d.getVar('SWUPDATE_IS_RDIFF_UPDATE') != "true").lower() # Variable that determines if SWU update is based on images or not. SWUPDATE_IS_IMAGES_UPDATE = "${@update_based_on_images(d)}" @@ -77,8 +97,16 @@ UBOOTIMG_OFFSET ?= "${BOOTLOADER_SEEK_BOOT}" ########## SWU Update Script ########## ####################################### +# Retrieve the correct update script name based on the SWU update type. +def get_update_script_name(d): + if d.getVar('SWUPDATE_IS_FILES_UPDATE') == "true": + return "update_files.sh" + if d.getVar('SWUPDATE_IS_RDIFF_UPDATE') == "true": + return "update_rdiff.sh" + return "update_images.sh" + # Initialize variable that configures the update script to use. -SWUPDATE_SCRIPT ?= "${@oe.utils.vartrue('SWUPDATE_IS_FILES_UPDATE', 'update_files.sh', 'update_images.sh', d)}" +SWUPDATE_SCRIPT ?= "${@get_update_script_name(d)}" # Name of the update script to include in the SWU package. SWUPDATE_SCRIPT_NAME = "${@os.path.basename(d.getVar('SWUPDATE_SCRIPT'))}" diff --git a/meta-digi-dey/classes/dey-swupdate.bbclass b/meta-digi-dey/classes/dey-swupdate.bbclass index eb351c1fd..15e0e3c29 100644 --- a/meta-digi-dey/classes/dey-swupdate.bbclass +++ b/meta-digi-dey/classes/dey-swupdate.bbclass @@ -14,6 +14,8 @@ # Load commmon variables. inherit dey-swupdate-common +DEPENDS += "${@oe.utils.ifelse(d.getVar('SWUPDATE_IS_RDIFF_UPDATE') == 'true', 'librsync-native', '')}" + ####################################### ###### SWU Update based on files ###### ####################################### @@ -60,3 +62,26 @@ create_swupdate_targz_file() { gzip "${targzfile%.*}" } ROOTFS_POSTPROCESS_COMMAND:append = "${@oe.utils.conditional('SWUPDATE_IS_FILES_UPDATE', 'true', ' create_swupdate_targz_file;', '', d)}" + +####################################### +###### SWU Update based on RDIFF ###### +####################################### + +create_swupdate_rdiff_file() { + local signature_file="${DEPLOY_DIR_IMAGE}/swupdate_rootfs_rdiff.sig" + local rootfs_rdiff_file="${DEPLOY_DIR_IMAGE}/${SWUPDATE_RDIFF_ROOTFS_DELTA_FILE_NAME}" + local rootfs_file="${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.squashfs" + + # Clean previous versions of the files. + rm -f "${signature_file}" "${rootfs_rdiff_file}" + + # Create signature file. + rdiff signature "${SWUPDATE_RDIFF_ROOTFS_SOURCE_FILE}" "${signature_file}" + + # Create the delta file. + rdiff delta "${signature_file}" "${rootfs_file}" "${rootfs_rdiff_file}" + + # Clean intermediates. + rm -f "${signature_file}" +} +IMAGE_POSTPROCESS_COMMAND:append = "${@oe.utils.conditional('SWUPDATE_IS_RDIFF_UPDATE', 'true', ' create_swupdate_rdiff_file;', '', d)}" diff --git a/meta-digi-dey/recipes-digi/swu-images/files/image_template_rdiff_mmc b/meta-digi-dey/recipes-digi/swu-images/files/image_template_rdiff_mmc new file mode 100644 index 000000000..6ca186650 --- /dev/null +++ b/meta-digi-dey/recipes-digi/swu-images/files/image_template_rdiff_mmc @@ -0,0 +1,8 @@ + { + type = "rdiff_image"; + filename = "@@SWUPDATE_RDIFF_ROOTFS_DELTA_FILE_NAME@@"; + device = "##DEV##"; + properties: { + rdiffbase = ["/dev/rdiff_source_rootfs"]; + }; + } diff --git a/meta-digi-dey/recipes-digi/swu-images/files/image_template_rdiff_nand b/meta-digi-dey/recipes-digi/swu-images/files/image_template_rdiff_nand new file mode 100644 index 000000000..88585fa5b --- /dev/null +++ b/meta-digi-dey/recipes-digi/swu-images/files/image_template_rdiff_nand @@ -0,0 +1,9 @@ + { + type = "ubivol_rdiff_image"; + filename = "@@SWUPDATE_RDIFF_ROOTFS_DELTA_FILE_NAME@@"; + volume = "##DEV##"; + properties: { + rdiffbase = ["/dev/rdiff_source_rootfs"]; + rdiffnewsize = "$swupdate_get_size(@@DEPLOY_DIR_IMAGE@@/@@IMG_NAME@@-@@MACHINE@@.squashfs)"; + }; + } diff --git a/meta-digi-dey/recipes-digi/swu-images/files/sw-description-rdiff_template b/meta-digi-dey/recipes-digi/swu-images/files/sw-description-rdiff_template new file mode 100644 index 000000000..ad06f926d --- /dev/null +++ b/meta-digi-dey/recipes-digi/swu-images/files/sw-description-rdiff_template @@ -0,0 +1,49 @@ +software = +{ + version = "@@DEY_FIRMWARE_VERSION@@"; + description = "@@SWUPDATE_DESCRIPTION@@"; + + @@SWUPDATE_STORAGE_TYPE@@ = { + primary: { + images: ( + ##IMAGES_PRIMARY## + ); + scripts: ( + { + filename = "@@SWUPDATE_SCRIPT_NAME@@"; + type = "shellscript"; + data = "$swupdate_get_sha256(@@SWUPDATE_RDIFF_ROOTFS_SOURCE_FILE@@)" + sha256 = "$swupdate_get_sha256(@@SWUPDATE_SCRIPT_NAME@@)"; + } + ); + uboot: ( + { + name = "upgrade_available"; + value = "1"; + } + ); + } + secondary: { + images: ( + ##IMAGES_SECONDARY## + ); + scripts: ( + { + filename = "@@SWUPDATE_SCRIPT_NAME@@"; + type = "shellscript"; + data = "$swupdate_get_sha256(@@SWUPDATE_RDIFF_ROOTFS_SOURCE_FILE@@)" + sha256 = "$swupdate_get_sha256(@@SWUPDATE_SCRIPT_NAME@@)"; + } + ); + uboot: ( + { + name = "upgrade_available"; + value = "1"; + } + ); + } + platform = { + ref = "#./primary"; + } + }; +} diff --git a/meta-digi-dey/recipes-digi/swu-images/files/update_rdiff.sh b/meta-digi-dey/recipes-digi/swu-images/files/update_rdiff.sh new file mode 100755 index 000000000..aca86d7f5 --- /dev/null +++ b/meta-digi-dey/recipes-digi/swu-images/files/update_rdiff.sh @@ -0,0 +1,206 @@ +#!/bin/sh +#=============================================================================== +# +# update_rdiff +# +# Copyright (C) 2023 by Digi International Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# +# !Description: SWU update rdiff script +# +#=============================================================================== + +# Sanity check. This script should be always executed with at least one argument. +if [ $# -lt 1 ]; then + exit 1; +fi + +# Sanity check. Do not run in single-boot systems. +[ "$(fw_printenv -n dualboot)" = "yes" ] || { echo "This update cannot be applied to single-boot systems, aborting..."; exit 1; } + +# Sanity check. Do not run in R/W systems. +if ! grep "/proc/mounts" -qe "squashfs"; then + echo "This update cannot be applied to R/W systems, aborting..." + exit 1 +fi + +# Variables. +BLOCK_SIZE=4096 +ROOTFS_NAME="rootfs" +ROOTFS_SOURCE_ENDPOINT="/dev/rdiff_source_rootfs" +ROOTFS_DEV_BLOCK="mmcblk0p3" +ROOTFS_DEV_BLOCK_A="mmcblk0p3" +ROOTFS_DEV_BLOCK_B="mmcblk0p4" + +# Determines whether the file system type is UBIFS or not. +is_ubifs() { + [ -c "/dev/ubi0" ] +} + +# Determines whether the system is dualboot or not. +is_dualboot() { + [ "$(fw_printenv -n dualboot)" = "yes" ] +} + +# Retrieves the dualboot active system letter. +# +# Returns: +# The dualboot active system letter: 'a' for primary, 'b' for secondary. +get_active_system() { + local active_system="$(fw_printenv -n active_system)" + echo "${active_system}" | cut -d_ -f2 +} + +# Retrieves the MTD partition number corresponding to the given partition name. +# +# Args: +# $1: partition name. +# +# Returns: +# The MTD partition number corresponding to the given partition name, -1 if +# not found. +get_mtd_number() { + local mtd_line="$(sed -ne "/${1}/s,^mtd\([0-9]\+\).*,\1,g;T;p" /proc/mtd)" + echo "${mtd_line:--1}" +} + +# Creates the UBI device for the given MTD partition number. +# +# Args: +# $1: the MTD partition number to create the UBI device for. +# +# Returns: +# The created UBI device number for the given MTD partition number, -1 if error. +create_ubi_device() { + local dev_number="$(ubiattach -m "${1}" 2>/dev/null | sed -ne 's,.*device number \([0-9]\).*,\1,g;T;p' 2>/dev/null)" + echo "${dev_number:--1}" +} + +# Retrieves the UBI device number containing the given partition name. If the +# device does not exist, the method attempts to create it based on the MTD dev +# number containing the desired partition. +# +# Args: +# $1: partition name. +# +# Returns: +# The UBI device number containing the given partition name, -1 if not found. +get_ubi_device() { + local ubi_devices="$(ubinfo | grep "Present UBI devices:" | cut -d ":" -f2 | xargs | sed -e 's/,//g')" + for ubi_device in ${ubi_devices}; do + if ubinfo "/dev/${ubi_device}" -a | grep -qe "Name:.*$1"; then + echo "${ubi_device}" | tr -dc '0-9' + return 0 + fi + done + + # Look for the MTD number containing the given partition name. + local mtd_num="$(get_mtd_number "${1}")" + if [ "${mtd_num}" = "-1" ]; then + echo "-1" + return 1 + else + # Create the UBI device. + ubi_device_number="$(create_ubi_device "${mtd_num}")" + echo "${ubi_device_number}" + fi +} + +# Retrieves the UBI volume containing the given partition name. +# +# Args: +# $1: partition name. +# +# Returns: +# The UBI volume containing the given partition name, -1 if not found. +get_ubi_volume() { + # Look for the UBI device containing given partition. + local ubi_device="$(get_ubi_device "${1}")" + if [ "${ubi_device}" = "-1" ]; then + echo "-1" + return 1 + fi + # Look for the UBI volume containing given partition. + local ubi_volume="$(ubinfo -d "${ubi_device}" -N "${1}" | grep "Volume ID" | cut -d ":" -f2 | xargs | cut -d " " -f1)" + if [ -z "${ubi_volume}" ]; then + echo "-1" + return 1 + fi + echo "ubi${ubi_device}_${ubi_volume}" +} + +# Creates the 'rootfs' source endpoint. +# +# Update source for the 'rootfs' partition cannot be determined at build time. For MTD +# devices, it depends on whether system is based on single or multiple MTD partitions. +# For this reason, hook the source update to a well known endpoint and just create the +# required link from the running system once all the information is available. +create_source_endpoint() { + # Initialize vars. Assume system is MMC based. + local rootfs_source_partiton="${ROOTFS_NAME}" + local rootfs_source_dev="${ROOTFS_DEV_BLOCK}" + + # Remove previous link. + [ -L "${ROOTFS_SOURCE_ENDPOINT}" ] && unlink "${ROOTFS_SOURCE_ENDPOINT}" + + # Update variables for dualboot systems. + if is_dualboot; then + local active_part="$(get_active_system)" + rootfs_source_partiton="${rootfs_source_partiton}_${active_part}" + if [ "${active_part}" = "a" ]; then + rootfs_source_dev=${ROOTFS_DEV_BLOCK_A} + else + rootfs_source_dev=${ROOTFS_DEV_BLOCK_B} + fi + fi + + # Update variables for MTD systems. + if is_ubifs; then + # Look for 'rootfs' source UBI volume. + rootfs_source_dev="$(get_ubi_volume "${rootfs_source_partiton}")" + [ "${rootfs_source_dev}" = "-1" ] && { echo "Unable to find UBI volume containing '${rootfs_source_partiton}' partition."; exit 1; } + fi + + # Create link. + ln -s "${rootfs_source_dev}" "${ROOTFS_SOURCE_ENDPOINT}" +} + +# Validates the base image before applying the RDIFF patch. +# +# Args: +# $1: Checksum of original base image. +validate_base_image() { + local fs_size="$(hexdump -s 0x28 -n 4 -e '1/4 "%d"' "${ROOTFS_SOURCE_ENDPOINT}")" + fs_size=$(( (fs_size + 0xfff) & 0xfffff000 )) + local n_blocks=$(( fs_size/BLOCK_SIZE )) + local checksum="$(dd if="${ROOTFS_SOURCE_ENDPOINT}" bs="${BLOCK_SIZE}" count="${n_blocks}" 2> /dev/null | sha256sum | cut -d " " -f1)" + + if [ "${checksum}" != "${1}" ]; then + echo "[ERROR] Base image is not the expected one or has been modified. Aborting update..." + exit 1 + fi +} + +# Called just before installation process starts. +if [ "${1}" = "preinst" ]; then + create_source_endpoint + validate_base_image "${2}" + + # TODO: Execute custom code here. For example: + # - Mount additional devices/partitions. + # - Stop services/process before installation. +fi + +# Called just after installation process ends. +if [ "${1}" = "postinst" ]; then + : + + # TODO: Execute custom code here. For example: + # - Clean files/directories. + # - Post-process files. +fi diff --git a/meta-digi-dey/recipes-digi/swu-images/swu.inc b/meta-digi-dey/recipes-digi/swu-images/swu.inc index 1332116de..94199300f 100644 --- a/meta-digi-dey/recipes-digi/swu-images/swu.inc +++ b/meta-digi-dey/recipes-digi/swu-images/swu.inc @@ -8,13 +8,17 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171d SRC_URI = " \ file://sw-description-images_template \ file://sw-description-files_template \ + file://sw-description-rdiff_template \ file://sw-description-uboot \ file://swupdate_uboot_nand.sh \ file://swupdate_uboot_mmc.sh \ file://image_template_mmc \ file://image_template_nand \ + file://image_template_rdiff_mmc \ + file://image_template_rdiff_nand \ file://update_images.sh \ file://update_files.sh \ + file://update_rdiff.sh \ " inherit swupdate dey-swupdate-common @@ -26,6 +30,7 @@ INHIBIT_SWUPDATE_ADD_SRC_URI = "true" SWUPDATE_IMAGES = " \ ${@oe.utils.ifelse(d.getVar('SWUPDATE_IS_IMAGES_UPDATE') == 'true', '${IMG_NAME}', '')} \ ${@oe.utils.ifelse(d.getVar('SWUPDATE_IS_FILES_UPDATE') == 'true', '${SWUPDATE_FILES_TARGZ_FILE_NAME}', '')} \ + ${@oe.utils.ifelse(d.getVar('SWUPDATE_IS_RDIFF_UPDATE') == 'true', '${IMG_NAME} ${SWUPDATE_RDIFF_ROOTFS_DELTA_FILE_NAME}', '')} \ ${@oe.utils.ifelse(d.getVar('SWUPDATE_UBOOTIMG') == 'true', '${UBOOT_PREFIX}', '')} \ ${@oe.utils.ifelse(d.getVar('SWUPDATE_UBOOTIMG') == 'true', '${SWUPDATE_UBOOT_SCRIPT}', '')} \ ${SWUPDATE_SCRIPT_NAME} \ @@ -33,7 +38,9 @@ SWUPDATE_IMAGES = " \ # Associate images and file types. python () { - img_fstypes = d.getVar('BOOTFS_EXT') + " " + d.getVar('ROOTFS_EXT') + img_fstypes = d.getVar('BOOTFS_EXT') + if d.getVar('SWUPDATE_IS_IMAGES_UPDATE') == "true": + img_fstypes = img_fstypes + " " + d.getVar('ROOTFS_EXT') d.setVarFlag("SWUPDATE_IMAGES_FSTYPES", d.getVar('IMG_NAME'), img_fstypes) if (d.getVar('SWUPDATE_UBOOTIMG') == "true"): uboot_fstypes = d.getVar('UBOOT_EXT') @@ -75,6 +82,8 @@ fill_description() { sed -i -e "s,##UBOOTIMG_OFFSET##,${UBOOTIMG_OFFSET},g" "${WORKDIR}/sw-description" elif [ "${SWUPDATE_IS_FILES_UPDATE}" = "true" ]; then cp ${WORKDIR}/sw-description-files_template ${WORKDIR}/sw-description + elif [ "${SWUPDATE_IS_RDIFF_UPDATE}" = "true" ]; then + cp ${WORKDIR}/sw-description-rdiff_template ${WORKDIR}/sw-description else cp ${WORKDIR}/sw-description-images_template ${WORKDIR}/sw-description fi @@ -87,26 +96,35 @@ fill_description() { BOOT_IMAGE_NAME="${IMG_NAME}-${MACHINE}${BOOTFS_EXT}" ROOTFS_IMAGE_NAME="${IMG_NAME}-${MACHINE}${ROOTFS_EXT}" + # Set correct image templates. + BOOT_IMAGE_TEMPLATE="${SWUPDATE_IMAGES_IMAGE_TEMPLATE_FILE}" + ROOTFS_IMAGE_TEMPLATE="${SWUPDATE_IMAGES_IMAGE_TEMPLATE_FILE}" + if [ "${SWUPDATE_IS_RDIFF_UPDATE}" = "true" ]; then + ROOTFS_IMAGE_TEMPLATE="${SWUPDATE_RDIFF_IMAGE_TEMPLATE_FILE}" + fi + # Add primary bank images section for dual boot systems. printf "%s,\n%s\n" \ - "$(sed -e "s,##IMG_NAME##,${BOOT_IMAGE_NAME},g" -e "s,##DEV##,${BOOT_DEV_NAME_A},g" -e "/compressed/d" "${SWUPDATE_IMAGES_IMAGE_TEMPLATE_FILE}")" \ - "$(sed -e "s,##IMG_NAME##,${ROOTFS_IMAGE_NAME},g" -e "s,##DEV##,${ROOTFS_DEV_NAME_A},g" "${SWUPDATE_IMAGES_IMAGE_TEMPLATE_FILE}")" \ + "$(sed -e "s,##IMG_NAME##,${BOOT_IMAGE_NAME},g" -e "s,##DEV##,${BOOT_DEV_NAME_A},g" -e "/compressed/d" "${BOOT_IMAGE_TEMPLATE}")" \ + "$(sed -e "s,##IMG_NAME##,${ROOTFS_IMAGE_NAME},g" -e "s,##DEV##,${ROOTFS_DEV_NAME_A},g" "${ROOTFS_IMAGE_TEMPLATE}")" \ > images_temp.txt sed -i -e "/##IMAGES_PRIMARY##/r images_temp.txt" -e "/##IMAGES_PRIMARY##/d" "${WORKDIR}/sw-description" # Add secondary bank images section for dual boot systems. printf "%s,\n%s\n" \ - "$(sed -e "s,##IMG_NAME##,${BOOT_IMAGE_NAME},g" -e "s,##DEV##,${BOOT_DEV_NAME_B},g" -e "/compressed/d" "${SWUPDATE_IMAGES_IMAGE_TEMPLATE_FILE}")" \ - "$(sed -e "s,##IMG_NAME##,${ROOTFS_IMAGE_NAME},g" -e "s,##DEV##,${ROOTFS_DEV_NAME_B},g" "${SWUPDATE_IMAGES_IMAGE_TEMPLATE_FILE}")" \ + "$(sed -e "s,##IMG_NAME##,${BOOT_IMAGE_NAME},g" -e "s,##DEV##,${BOOT_DEV_NAME_B},g" -e "/compressed/d" "${BOOT_IMAGE_TEMPLATE}")" \ + "$(sed -e "s,##IMG_NAME##,${ROOTFS_IMAGE_NAME},g" -e "s,##DEV##,${ROOTFS_DEV_NAME_B},g" "${ROOTFS_IMAGE_TEMPLATE}")" \ > images_temp.txt sed -i -e "/##IMAGES_SECONDARY##/r images_temp.txt" -e "/##IMAGES_SECONDARY##/d" "${WORKDIR}/sw-description" # Add images section for single boot systems. - printf "%s,\n%s\n" \ - "$(sed -e "s,##IMG_NAME##,${BOOT_IMAGE_NAME},g" -e "s,##DEV##,${BOOT_DEV_NAME},g" -e "/compressed/d" "${SWUPDATE_IMAGES_IMAGE_TEMPLATE_FILE}")" \ - "$(sed -e "s,##IMG_NAME##,${ROOTFS_IMAGE_NAME},g" -e "s,##DEV##,${ROOTFS_DEV_NAME_FINAL},g" "${SWUPDATE_IMAGES_IMAGE_TEMPLATE_FILE}")" \ - > images_temp.txt - sed -i -e "/##IMAGES_SINGLE##/r images_temp.txt" -e "/##IMAGES_SINGLE##/d" "${WORKDIR}/sw-description" + if [ "${SWUPDATE_IS_RDIFF_UPDATE}" != "true" ]; then + printf "%s,\n%s\n" \ + "$(sed -e "s,##IMG_NAME##,${BOOT_IMAGE_NAME},g" -e "s,##DEV##,${BOOT_DEV_NAME},g" -e "/compressed/d" "${BOOT_IMAGE_TEMPLATE}")" \ + "$(sed -e "s,##IMG_NAME##,${ROOTFS_IMAGE_NAME},g" -e "s,##DEV##,${ROOTFS_DEV_NAME_FINAL},g" "${ROOTFS_IMAGE_TEMPLATE}")" \ + > images_temp.txt + sed -i -e "/##IMAGES_SINGLE##/r images_temp.txt" -e "/##IMAGES_SINGLE##/d" "${WORKDIR}/sw-description" + fi # Remove 'compressed' flag for read-only file systems as they use 'squashfs' images. if [ -n "${@bb.utils.contains('IMAGE_FEATURES', 'read-only-rootfs', '1', '', d)}" ]; then