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:
parent
1ec5cc172c
commit
1105a8fecd
|
|
@ -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}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
#===============================================================================
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
"
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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";
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue