dualboot: move contents of meta-digi-dualboot layer into meta-digi as a class

- create dualboot.bbclass that
  - sets DUALBOOT_ENABLED variable
  - defines partition names and function for changing the sw-description
    for swupdate
- move files from layer into meta-digi

https://onedigi.atlassian.net/browse/DEL-7962

Signed-off-by: Hector Palacios <hector.palacios@digi.com>

Signed-off-by: Francisco Gil <francisco.gilmartinez@digi.com>
This commit is contained in:
Hector Palacios 2022-08-08 22:06:44 +02:00 committed by Francisco Gil
parent 1ec5cc172c
commit 1105a8fecd
16 changed files with 692 additions and 2 deletions

View File

@ -25,6 +25,7 @@ SRC_URI = " \
file://install_linux_fw_sd.txt \
file://install_linux_fw_usb.txt \
${@oe.utils.conditional('UBOOT_HAS_FASTBOOT', 'true', 'file://install_linux_fw_uuu.sh', '', d)} \
${@oe.utils.vartrue('DUALBOOT_ENABLED', 'file://altboot.txt', '', d)} \
"
BOOTLOADER_IMAGE_RECIPE ?= "u-boot"
@ -184,6 +185,11 @@ do_deploy:append() {
sed -e "${TF_BOOTSCRIPT_SEDFILTER}" ${WORKDIR}/boot.txt > ${TMP_BOOTSCR}
mkimage -T script -n bootscript -C none -d ${TMP_BOOTSCR} ${DEPLOYDIR}/boot.scr
# Alternate boot script for dualboot
if [ "${DUALBOOT_ENABLED}" = "true" ]; then
mkimage -T script -n "Alternate bootscript" -C none -d ${WORKDIR}/altboot.txt ${DEPLOYDIR}/altboot.scr
fi
# Sign the scripts
if [ "${TRUSTFENCE_SIGN}" = "1" ]; then
export CONFIG_SIGN_KEYS_PATH="${TRUSTFENCE_SIGN_KEYS_PATH}"
@ -194,6 +200,13 @@ do_deploy:append() {
TMP_SIGNED_BOOTSCR="$(mktemp ${WORKDIR}/bootscr-signed.XXXXXX)"
trustfence-sign-artifact.sh -p "${DIGI_FAMILY}" -b "${DEPLOYDIR}/boot.scr" "${TMP_SIGNED_BOOTSCR}"
mv "${TMP_SIGNED_BOOTSCR}" "${DEPLOYDIR}/boot.scr"
if [ "${DUALBOOT_ENABLED}" = "true" ]; then
# Sign boot script
TMP_SIGNED_BOOTSCR="$(mktemp ${WORKDIR}/altboot-signed.XXXXXX)"
trustfence-sign-artifact.sh -p "${DIGI_FAMILY}" -b "${DEPLOYDIR}/altboot.scr" "${TMP_SIGNED_BOOTSCR}"
mv "${TMP_SIGNED_BOOTSCR}" "${DEPLOYDIR}/altboot.scr"
fi
fi
rm -f ${TMP_BOOTSCR}
}

View File

@ -0,0 +1,37 @@
#
# U-Boot bootscript for altbootcmd (dual boot fallback after retries)
#
# After an upgrade, active_system has changed. U-Boot tries to boot this system
# for a number of tries. If the limit is reached, altbootcmd is run instead.
# This is the script that it will run. It has to:
# * switch back to previous system
# * reset the firmware update flag
# * run the regular boot command
if test "${dualboot}" = "yes" && test "${upgrade_available}" = "1"; then
echo "## Update failed; Rolling back to previous version."
if test "${active_system}" = "linux_a"; then
setenv active_system linux_b
part number mmc ${mmcbootdev} linux_b linux_b_index
setexpr mmcpart ${linux_b_index}
# Save the partition index on variable rootfs_b_index
part number mmc ${mmcbootdev} rootfs_b rootfs_b_index
# Save the rootfs_b UUID into mmcroot_b
part uuid mmc ${mmcbootdev}:${rootfs_b_index} mmcroot_b
setenv mmcroot PARTUUID=${mmcroot_b}
else
setenv active_system linux_a
part number mmc ${mmcbootdev} linux_a linux_a_index
setexpr mmcpart ${linux_a_index}
# Save the partition index on variable rootfs_a_index
part number mmc ${mmcbootdev} rootfs_a rootfs_a_index
# Save the rootfs_a UUID into mmcroot_a
part uuid mmc ${mmcbootdev}:${rootfs_a_index} mmcroot_a
setenv mmcroot PARTUUID=${mmcroot_a}
fi
setenv upgrade_available
setenv bootcount 0
saveenv
fi
run bootcmd

View File

@ -0,0 +1,29 @@
#
# U-Boot bootscript for altbootcmd (dual boot fallback after retries)
#
# After an upgrade, active_system has changed. U-Boot tries to boot this system
# for a number of tries. If the limit is reached, altbootcmd is run instead.
# This is the script that it will run. It has to:
# * switch back to previous system
# * reset the firmware update flag
# * run the regular boot command
if test "${dualboot}" = "yes" && test "${upgrade_available}" = "1"; then
echo "## Update failed; Rolling back to previous version."
if test "${active_system}" = "linux_a"; then
setenv active_system linux_b
setenv mtdbootpart ${active_system}
setenv mtdrootfspart ${rootfsvol_b}
setenv rootfsvol ${rootfsvol_b}
else
setenv active_system linux_a
setenv mtdbootpart ${active_system}
setenv mtdrootfspart ${rootfsvol_a}
setenv rootfsvol ${rootfsvol_a}
fi
setenv upgrade_available
setenv bootcount 0
saveenv
fi
run bootcmd

View File

@ -0,0 +1,37 @@
#
# U-Boot bootscript for altbootcmd (dual boot fallback after retries)
#
# After an upgrade, active_system has changed. U-Boot tries to boot this system
# for a number of tries. If the limit is reached, altbootcmd is run instead.
# This is the script that it will run. It has to:
# * switch back to previous system
# * reset the firmware update flag
# * run the regular boot command
if test "${dualboot}" = "yes" && test "${upgrade_available}" = "1"; then
echo "## Update failed; Rolling back to previous version."
if test "${active_system}" = "linux_a"; then
setenv active_system linux_b
part number mmc ${mmcbootdev} linux_b linux_b_index
setexpr mmcpart ${linux_b_index}
# Save the partition index on variable rootfs_b_index
part number mmc ${mmcbootdev} rootfs_b rootfs_b_index
# Save the rootfs_b UUID into mmcroot_b
part uuid mmc ${mmcbootdev}:${rootfs_b_index} mmcroot_b
setenv mmcroot PARTUUID=${mmcroot_b}
else
setenv active_system linux_a
part number mmc ${mmcbootdev} linux_a linux_a_index
setexpr mmcpart ${linux_a_index}
# Save the partition index on variable rootfs_a_index
part number mmc ${mmcbootdev} rootfs_a rootfs_a_index
# Save the rootfs_a UUID into mmcroot_a
part uuid mmc ${mmcbootdev}:${rootfs_a_index} mmcroot_a
setenv mmcroot PARTUUID=${mmcroot_a}
fi
setenv upgrade_available
setenv bootcount 0
saveenv
fi
run bootcmd

View File

@ -0,0 +1,37 @@
#
# U-Boot bootscript for altbootcmd (dual boot fallback after retries)
#
# After an upgrade, active_system has changed. U-Boot tries to boot this system
# for a number of tries. If the limit is reached, altbootcmd is run instead.
# This is the script that it will run. It has to:
# * switch back to previous system
# * reset the firmware update flag
# * run the regular boot command
if test "${dualboot}" = "yes" && test "${upgrade_available}" = "1"; then
echo "## Update failed; Rolling back to previous version."
if test "${active_system}" = "linux_a"; then
setenv active_system linux_b
part number mmc ${mmcbootdev} linux_b linux_b_index
setexpr mmcpart ${linux_b_index}
# Save the partition index on variable rootfs_b_index
part number mmc ${mmcbootdev} rootfs_b rootfs_b_index
# Save the rootfs_b UUID into mmcroot_b
part uuid mmc ${mmcbootdev}:${rootfs_b_index} mmcroot_b
setenv mmcroot PARTUUID=${mmcroot_b}
else
setenv active_system linux_a
part number mmc ${mmcbootdev} linux_a linux_a_index
setexpr mmcpart ${linux_a_index}
# Save the partition index on variable rootfs_a_index
part number mmc ${mmcbootdev} rootfs_a rootfs_a_index
# Save the rootfs_a UUID into mmcroot_a
part uuid mmc ${mmcbootdev}:${rootfs_a_index} mmcroot_a
setenv mmcroot PARTUUID=${mmcroot_a}
fi
setenv upgrade_available
setenv bootcount 0
saveenv
fi
run bootcmd

View File

@ -0,0 +1,29 @@
# Adds DualBoot configuration
#
# To use it add the following line to conf/local.conf:
#
# INHERIT += "dualboot"
#
DUALBOOT_ENABLED ?= "true"
# U-Boot altboot script
BOOT_SCRIPTS += "altboot.scr:altboot.scr"
# Dual boot partition names for eMMC or MTD
BOOT_DEV_NAME_A ?= "${@bb.utils.contains('STORAGE_MEDIA', 'mmc', '/dev/mmcblk0p1', 'linux_a', d)}"
BOOT_DEV_NAME_B ?= "${@bb.utils.contains('STORAGE_MEDIA', 'mmc', '/dev/mmcblk0p2', 'linux_b', d)}"
ROOTFS_DEV_NAME_A ?= "${@bb.utils.contains('STORAGE_MEDIA', 'mmc', '/dev/mmcblk0p3', 'rootfs_a', d)}"
ROOTFS_DEV_NAME_B ?= "${@bb.utils.contains('STORAGE_MEDIA', 'mmc', '/dev/mmcblk0p4', 'rootfs_b', d)}"
fill_description_dualboot () {
sed -i -e "s,##BOOTIMG_NAME##,${IMG_NAME}-${MACHINE}${BOOTFS_EXT},g" "${WORKDIR}/sw-description-dualboot"
sed -i -e "s,##BOOT_DEV_A##,${BOOT_DEV_NAME_A},g" "${WORKDIR}/sw-description-dualboot"
sed -i -e "s,##BOOT_DEV_B##,${BOOT_DEV_NAME_B},g" "${WORKDIR}/sw-description-dualboot"
sed -i -e "s,##ROOTIMG_NAME##,${IMG_NAME}-${MACHINE}${ROOTFS_EXT},g" "${WORKDIR}/sw-description-dualboot"
sed -i -e "s,##ROOTFS_DEV_A##,${ROOTFS_DEV_NAME_A},g" "${WORKDIR}/sw-description-dualboot"
sed -i -e "s,##ROOTFS_DEV_B##,${ROOTFS_DEV_NAME_B},g" "${WORKDIR}/sw-description-dualboot"
sed -i -e "s,##SW_VERSION##,${SOFTWARE_VERSION},g" "${WORKDIR}/sw-description-dualboot"
# Overwrite the sw-description with the dualboot version
mv ${WORKDIR}/sw-description-dualboot ${WORKDIR}/sw-description
}

View File

@ -36,6 +36,7 @@ RDEPENDS:${PN} = "\
connectcore-demo-example \
cloudconnector \
cryptodev-module \
${@oe.utils.vartrue('DUALBOOT_ENABLED', 'dualboot', 'recovery-utils', d)} \
${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'firmwared', '',d)} \
${@bb.utils.contains("MACHINE_FEATURES", "keyboard", "${VIRTUAL-RUNTIME_keymaps}", "", d)} \
${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '', bb.utils.contains("MACHINE_FEATURES", "rtc", "${VIRTUAL-RUNTIME_base-utils-hwclock}", "", d), d)} \
@ -51,7 +52,6 @@ RDEPENDS:${PN} = "\
networkmanager-nmcli \
os-release \
${@bb.utils.contains('MACHINE_FEATURES', 'pci', 'pciutils', '',d)} \
recovery-utils \
sysinfo \
${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'system-monitor', '',d)} \
usbutils \

View File

@ -0,0 +1,48 @@
From: Hector Palacios <hector.palacios@digi.com>
Date: Thu, 8 Jul 2021 09:43:50 +0200
Subject: [PATCH] cc.conf: pre-set for dual boot mode
- Change default firmware download path to external media
'/home/root/'.
- Remove '/mnt/update' virtual directory.
- Enable dual boot mode.
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
---
app/cfg_files/cc.conf | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/app/cfg_files/cc.conf b/app/cfg_files/cc.conf
index 7018efb..bff9332 100644
--- a/app/cfg_files/cc.conf
+++ b/app/cfg_files/cc.conf
@@ -99,27 +99,22 @@ virtual-dirs
vdir {
name = "tmp"
path = "/tmp"
}
- vdir {
- name = "update"
- path = "/mnt/update"
- }
-
vdir {
name = "media"
path = "/run/media"
}
}
# Firmware Download Path: Absolute path to download the firmware packages from
# the cloud. It must be an existing directory.
-firmware_download_path = /mnt/update
+firmware_download_path = /home/root
# Enable dualboot support
-dualboot = false
+dualboot = true
# Enables on the fly firmware update support
on_the_fly = false
#===============================================================================

View File

@ -19,6 +19,7 @@ SRC_URI = " \
${CC_GIT_URI};branch=${SRCBRANCH} \
file://cloud-connector-init \
file://cloud-connector.service \
${@oe.utils.vartrue('DUALBOOT_ENABLED', 'file://0001-cc.conf-pre-set-for-dual-boot-mode.patch', '', d)} \
"
S = "${WORKDIR}/git"

View File

@ -0,0 +1,84 @@
# Copyright (C) 2021 Digi International Inc.
SUMMARY = "Digi Embedded Yocto Dual boot support"
SECTION = "base"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6"
# When building a TrustFence enabled rootfs, we need the TrustFence PKI tree to
# be already generated in order to copy the public key. Forcing a dependency with
# 'virtual/kernel' ensures that the keys are already generated as they are needed to sign the
# kernel artifacts.
DEPENDS += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'virtual/kernel openssl-native', '', d)}"
SRC_URI = " \
file://dualboot-init \
file://firmware-update-dual.sh \
file://firmware-update-check.service \
file://on-the-fly-swap-partition.sh \
"
S = "${WORKDIR}"
inherit systemd update-rc.d
do_install() {
install -d ${D}${sysconfdir}/init.d/
install -m 0755 ${WORKDIR}/dualboot-init ${D}${sysconfdir}/dualboot-init
ln -sf /etc/dualboot-init ${D}${sysconfdir}/init.d/dualboot-init
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/firmware-update-dual.sh ${D}${bindir}
install -m 0755 ${WORKDIR}/on-the-fly-swap-partition.sh ${D}${bindir}
install -d ${D}${systemd_unitdir}/system/
install -m 0644 ${WORKDIR}/firmware-update-check.service ${D}${systemd_unitdir}/system/
# If Trustfence is enabled, copy the public key that is going to be used into the
# initramfs '/etc/ssl/certs' folder in order to verify swupdate packages.
if [ "${TRUSTFENCE_SIGN}" = "1" ]; then
# Retrieve the key index to use.
KEY_INDEX="0"
if [ -n "${TRUSTFENCE_KEY_INDEX}" ]; then
KEY_INDEX="${TRUSTFENCE_KEY_INDEX}"
fi
KEY_INDEX_1=$(expr ${KEY_INDEX} + 1)
# Find the certificate to use.
if [ "${TRUSTFENCE_SIGN_MODE}" = "HAB" ]; then
CERT_IMG="$(echo ${TRUSTFENCE_SIGN_KEYS_PATH}/crts/IMG${KEY_INDEX_1}*crt.pem)"
elif [ "${TRUSTFENCE_SIGN_MODE}" = "AHAB" ]; then
CERT_IMG="$(echo ${TRUSTFENCE_SIGN_KEYS_PATH}/crts/SRK${KEY_INDEX_1}*_ca_crt.pem)"
else
bberror "Unkown TRUSTFENCE_SIGN_MODE value"
exit 1
fi
# Extract the public key from the certificate.
install -d ${D}${sysconfdir}/ssl/certs
openssl x509 -pubkey -noout -in "${CERT_IMG}" > ${D}${sysconfdir}/ssl/certs/key.pub
fi
}
FILES:${PN} += " \
${sysconfdir}/dualboot-init \
${sysconfdir}/init.d/dualboot-init \
${bindir}/firmware-update-dual.sh \
${bindir}/on-the-fly-swap-partition.sh \
${systemd_unitdir}/system/firmware-update-check.service \
${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', '${sysconfdir}/ssl/certs/key.pub', '', d)} \
"
INITSCRIPT_NAME = "dualboot-init"
INITSCRIPT_PARAMS = "start 19 2 3 4 5 . stop 21 0 1 6 ."
SYSTEMD_SERVICE = "firmware-update-check.service"
PACKAGE_ARCH = "${MACHINE_ARCH}"
# Add swupdate into the rootfs for dual boot support
RDEPENDS_${PN}-init = " \
swupdate \
trustfence-tool \
"

View File

@ -0,0 +1,56 @@
#!/bin/sh
#===============================================================================
#
# Copyright (C) 2021 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: Verifies successful boot
#
#===============================================================================
dualboot_init () {
ACTIVE_SYSTEM="$(fw_printenv -n active_system 2>/dev/null)"
if [ -z "${ACTIVE_SYSTEM}" ]; then
if grep -qs environment /proc/mtd; then
MTD_BOOT_PART="$(fw_printenv -n mtdbootpart 2>/dev/null)"
fw_setenv active_system "${MTD_BOOT_PART}"
else
BOOT_PART="$(fw_printenv -n mmcpart 2>/dev/null)"
BOOT_DEV="$(fw_printenv -n mmcbootdev 2>/dev/null)"
CURRENT_PART="$(ls -l /dev/disk/by-partlabel/ | grep -i mmcblk${BOOT_DEV}p${BOOT_PART} | awk '{print $9}')"
fw_setenv active_system "${CURRENT_PART}"
fi
fi
ISUPGRADING="$(fw_printenv -n upgrade_available 2>/dev/null)"
if [ "$ISUPGRADING" = "1" ]; then
BOOTCOUNT="$(fw_printenv -n bootcount 2>/dev/null)"
if [ "${BOOTCOUNT}" -lt 3 ]; then
fw_setenv upgrade_available
fw_setenv bootcount 0
fi
fi
}
case "$1" in
start)
echo -n "Starting dualboot check: "
dualboot_init
echo "done."
;;
stop)
;;
restart)
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac

View File

@ -0,0 +1,12 @@
[Unit]
Description=Verify if fw update was successful
After=default.target
[Service]
Type=simple
RemainAfterExit=no
ExecStart=/etc/dualboot-init start
TimeoutStartSec=0
[Install]
WantedBy=default.target

View File

@ -0,0 +1,149 @@
#!/bin/sh
#===============================================================================
#
# update-firmware-dual.sh
#
# Copyright (C) 2021 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: Dual boot firmware update script
#
#===============================================================================
SCRIPTNAME="$(basename $(readlink -f ${0}))"
VERBOSE=""
PUBLIC_KEY="/etc/ssl/certs/key.pub"
ACTIVE_SYSTEM="$(fw_printenv -n active_system 2>/dev/null)"
## Local functions
usage() {
cat <<EOF
Usage: ${SCRIPTNAME} [OPTIONS] </your-path/your-filename>.swu
-a Show currently active system
-v Enable verbosity
-h Show this help
EOF
}
show_active_system() {
if [ "${ACTIVE_SYSTEM}" = "linux_a" ]; then
echo "Active system is A"
else
echo "Active system is B"
fi
}
while :; do
case $1 in
-a|--active) show_active_system;exit
;;
-v|--verbose) VERBOSE="-v"
;;
-h|--help) usage;exit
;;
*) UPDATE_FILE="${1}"
break
;;
esac
shift
done
# Check update file parameter.
if [ -z "${UPDATE_FILE}" ]; then
echo "[ERROR] Update file not specified"
exit
fi
PARTTABLE="/proc/mtd"
MTDINDEX="$(sed -ne "s/\(^mtd[0-9]\+\):.*\<environment\>.*/\1/g;T;p" ${PARTTABLE} 2>/dev/null)"
if [ -z "${MTDINDEX}" ]; then
# Get Boot partition device and index.
BOOT_PART="$(fw_printenv -n mmcpart 2>/dev/null)"
BOOT_DEV="$(fw_printenv -n mmcbootdev 2>/dev/null)"
# Get current partition information so we can
# determine where to flash the images.
if [ "${ACTIVE_SYSTEM}" = "linux_a" ]; then
echo "Current system is A; Updating system on B"
KERNELBOOT="linux_b"
ROOTFS="rootfs_b"
IMAGE_SET="mmc,secondary"
else
echo "Current system is B; Updating system on A"
KERNELBOOT="linux_a"
ROOTFS="rootfs_a"
IMAGE_SET="mmc,primary"
fi
# get boot partition index
MMC_PART="$(ls -l /dev/disk/by-partlabel/ | grep -i ${KERNELBOOT} | awk '{print $11}' | sed -e 's/[../mmcblkp]//g' -e 's/^.//')"
# search rootfs UUID
MMCROOT_PART="$(ls -l /dev/disk/by-partlabel/ | grep -i ${ROOTFS} | awk '{print $11}' | sed -e 's/[../mmcblkp]//g' -e 's/^.//')"
PART_UUID="$(ls -l /dev/disk/by-partuuid/ | grep -i mmcblk${BOOT_DEV}p${MMCROOT_PART} | awk '{print $9}')"
echo ""
echo "Updating '${IMAGE_SET}' image set from '${UPDATE_FILE}'..."
echo ""
# Execute the update.
swupdate ${VERBOSE} -i "${UPDATE_FILE}" -e "${IMAGE_SET}"
if [ "$?" = "0" ]; then
fw_setenv mmcroot PARTUUID=${PART_UUID}
fw_setenv mmcpart ${MMC_PART}
fw_setenv active_system ${KERNELBOOT}
fw_setenv bootcount 0
echo "Firmware update finished; Rebooting system."
reboot -f
else
echo "[ERROR] $? There was an error performing the update"
fi
else
# Get current partition information so we can
# determine where to flash the images.
if [ "${ACTIVE_SYSTEM}" = "linux_a" ]; then
echo "Current system is A; Updating system on B"
KERNELBOOT="linux_b"
ROOTFS="rootfs_b"
IMAGE_SET="mtd,secondary"
else
echo "Current system is B; Updating system on A"
KERNELBOOT="linux_a"
ROOTFS="rootfs_a"
IMAGE_SET="mtd,primary"
fi
echo ""
echo "Updating '${IMAGE_SET}' image set from '${UPDATE_FILE}'..."
echo ""
# Umount the partition before the update.
umount /mnt/${KERNELBOOT}
# Execute the update.
if [ -f "${PUBLIC_KEY}" ]; then
swupdate ${VERBOSE} -i "${UPDATE_FILE}" -e "${IMAGE_SET}" -k "${PUBLIC_KEY}"
else
swupdate ${VERBOSE} -i "${UPDATE_FILE}" -e "${IMAGE_SET}"
fi
if [ "$?" = "0" ]; then
fw_setenv mtdbootpart ${KERNELBOOT}
fw_setenv mtdrootfspart ${ROOTFS}
fw_setenv rootfsvol ${ROOTFS}
fw_setenv active_system ${KERNELBOOT}
fw_setenv bootcount 0
echo "Firmware update finished; Rebooting system."
reboot -f
else
echo "[ERROR] $? There was an error performing the update"
fi
fi

View File

@ -0,0 +1,48 @@
#!/bin/sh
#===============================================================================
#
# on-the-fly-swap-partition.sh
#
# Copyright (C) 2021-2022 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: On the fly script to swap active partition
#
#===============================================================================
ACTIVE_SYSTEM="$(fw_printenv -n active_system 2>/dev/null)"
# Get current partition information so we can
# determine where to flash the images.
if [ "${ACTIVE_SYSTEM}" = "linux_a" ]; then
KERNELBOOT="linux_b"
ROOTFS="rootfs_b"
else
KERNELBOOT="linux_a"
ROOTFS="rootfs_a"
fi
if grep -qs environment /proc/mtd; then
fw_setenv mtdbootpart ${KERNELBOOT}
fw_setenv mtdrootfspart ${ROOTFS}
fw_setenv rootfsvol ${ROOTFS}
fw_setenv active_system ${KERNELBOOT}
else
# Get Boot partition device and index.
BOOT_DEV="$(fw_printenv -n mmcbootdev 2>/dev/null)"
# get boot partition index
MMC_PART="$(ls -l /dev/disk/by-partlabel/ | grep -i ${KERNELBOOT} | awk '{print $11}' | sed -e 's/[../mmcblkp]//g' -e 's/^.//')"
# search rootfs UUID
MMCROOT_PART="$(ls -l /dev/disk/by-partlabel/ | grep -i ${ROOTFS} | awk '{print $11}' | sed -e 's/[../mmcblkp]//g' -e 's/^.//')"
PART_UUID="$(ls -l /dev/disk/by-partuuid/ | grep -i mmcblk${BOOT_DEV}p${MMCROOT_PART} | awk '{print $9}')"
fw_setenv mmcroot PARTUUID=${PART_UUID}
fw_setenv mmcpart ${MMC_PART}
fw_setenv active_system ${KERNELBOOT}
fi

View File

@ -0,0 +1,107 @@
software =
{
version = "##SW_VERSION##";
mmc = {
primary: {
images: (
{
filename = "##BOOTIMG_NAME##";
device = "##BOOT_DEV_A##";
type = "raw";
sha256 = "@##BOOTIMG_NAME##";
installed-directly = true;
},
{
filename = "##ROOTIMG_NAME##";
device = "##ROOTFS_DEV_A##";
type = "raw";
sha256 = "@##ROOTIMG_NAME##";
compressed = "zlib";
installed-directly = true;
}
);
uboot: (
{
name = "upgrade_available";
value = "1";
}
);
}
secondary: {
images: (
{
filename = "##BOOTIMG_NAME##";
device = "##BOOT_DEV_B##";
type = "raw";
sha256 = "@##BOOTIMG_NAME##";
installed-directly = true;
},
{
filename = "##ROOTIMG_NAME##";
device = "##ROOTFS_DEV_B##";
type = "raw";
sha256 = "@##ROOTIMG_NAME##";
compressed = "zlib";
installed-directly = true;
}
);
uboot: (
{
name = "upgrade_available";
value = "1";
}
);
}
};
mtd = {
primary: {
images: (
{
filename = "##BOOTIMG_NAME##";
volume = "##BOOT_DEV_A##";
type = "ubivol";
sha256 = "@##BOOTIMG_NAME##";
installed-directly = true;
},
{
filename = "##ROOTIMG_NAME##";
volume = "##ROOTFS_DEV_A##";
type = "ubivol";
sha256 = "@##ROOTIMG_NAME##";
installed-directly = true;
}
);
uboot: (
{
name = "upgrade_available";
value = "1";
}
);
}
secondary: {
images: (
{
filename = "##BOOTIMG_NAME##";
volume = "##BOOT_DEV_B##";
type = "ubivol";
sha256 = "@##BOOTIMG_NAME##";
installed-directly = true;
},
{
filename = "##ROOTIMG_NAME##";
volume = "##ROOTFS_DEV_B##";
type = "ubivol";
sha256 = "@##ROOTIMG_NAME##";
installed-directly = true;
}
);
uboot: (
{
name = "upgrade_available";
value = "1";
}
);
}
};
}

View File

@ -10,7 +10,9 @@ SRC_URI = " \
file://sw-description-uboot \
file://swupdate_uboot_nand.sh \
file://swupdate_uboot_mmc.sh \
${@oe.utils.vartrue('DUALBOOT_ENABLED', 'file://sw-description-dualboot', '', d)} \
"
inherit swupdate
IMAGE_DEPENDS = "${@get_baseimg_pn(d)}"
@ -50,7 +52,8 @@ def get_baseimg_pn(d):
file_name = d.getVar('PN', True)
return file_name[:file_name.find("-swu")]
do_unpack[postfuncs] += "fill_description"
# Call regular substitution or dualboot substitution
do_unpack[postfuncs] += "${@oe.utils.vartrue('DUALBOOT_ENABLED', 'fill_description_dualboot', 'fill_description', d)}"
fill_description() {
if [ "${SWUPDATE_UBOOTIMG}" = "true" ]; then