Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TX2: Improve firmware writing speed #707

Merged
merged 2 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion layers/meta-balena
Submodule meta-balena updated 84 files
+1 −1 .github/workflows/bananapi-m1-plus.yml
+1 −1 .github/workflows/beaglebone-ai64.yml
+1 −1 .github/workflows/beaglebone-pocket.yml
+1 −1 .github/workflows/beaglebone.yml
+1 −1 .github/workflows/generic-aarch64.yml
+1 −1 .github/workflows/generic-amd64.yml
+1 −1 .github/workflows/genericx86-64-ext.yml
+1 −1 .github/workflows/genericx86-64.yml
+1 −1 .github/workflows/imx6ul-var-dart.yml
+1 −1 .github/workflows/imx7-var-som.yml
+1 −1 .github/workflows/iot-gate-imx8.yml
+1 −1 .github/workflows/iot-gate-imx8plus.yml
+1 −1 .github/workflows/jetson-agx-orin-devkit.yml
+1 −1 .github/workflows/jetson-nano.yml
+1 −1 .github/workflows/jetson-tx2.yml
+1 −1 .github/workflows/jetson-xavier.yml
+3 −3 .github/workflows/meta-balena-esr.yml
+1 −1 .github/workflows/nanopi-neo-air.yml
+1 −1 .github/workflows/nanopi-r2c.yml
+1 −1 .github/workflows/orangepi-plus2.yml
+1 −1 .github/workflows/owa5x.yml
+1 −1 .github/workflows/raspberrypi.yml
+1 −1 .github/workflows/raspberrypi2.yml
+1 −1 .github/workflows/raspberrypi3-64.yml
+1 −1 .github/workflows/raspberrypi3.yml
+1 −1 .github/workflows/raspberrypi4-64.yml
+1 −1 .github/workflows/revpi-connect-4.yml
+1 −1 .github/workflows/revpi-connect-s.yml
+1 −1 .github/workflows/revpi-connect.yml
+1 −1 .github/workflows/revpi-core-3.yml
+1 −1 .github/workflows/rockpi-4b-rk3399.yml
+1 −1 .github/workflows/surface-go.yml
+1 −1 .github/workflows/surface-pro-6.yml
+2 −2 .github/workflows/update-backports.yml
+1 −1 .github/workflows/var-som-mx6..yml
+918 −0 .versionbot/CHANGELOG.yml
+272 −0 CHANGELOG.md
+23 −19 README.md
+1 −1 meta-balena-common/classes/kernel-balena.bbclass
+2 −1 meta-balena-common/conf/distro/include/balena-os.inc
+1 −1 meta-balena-common/recipes-bsp/efitools/efitools.inc
+3 −7 meta-balena-common/recipes-connectivity/modemmanager/balena-files/0001-increase-qmi-port-open-timeout.patch
+18 −21 ...ipes-connectivity/modemmanager/balena-files/0002-quectel-disable-qmi-unsolicited-profile-manager-even.patch
+3 −6 ...ipes-connectivity/modemmanager/balena-files/0003-broadband-modem-qmi-quectel-fix-task-completion-when.patch
+1 −4 meta-balena-common/recipes-connectivity/modemmanager/balena-files/0004-bearer-qmi-Fix-SIM7100E-crash.patch
+1 −1 meta-balena-common/recipes-containers/balena-supervisor/balena-supervisor.inc
+3 −2 meta-balena-common/recipes-core/balena-rollback/files/rollback-parse-bootloader
+21 −3 meta-balena-common/recipes-core/initrdscripts/files/abroot
+4 −0 meta-balena-common/recipes-core/initrdscripts/files/cryptsetup-efi-tpm
+22 −3 meta-balena-common/recipes-core/initrdscripts/files/resindataexpander
+1 −0 meta-balena-common/recipes-core/os-config/os-config.inc
+96 −0 meta-balena-common/recipes-core/os-config/os-config/0002-Add-auth.-header-to-os-v1-config-requests.patch
+2 −0 meta-balena-common/recipes-core/packagegroups/packagegroup-resin.inc
+13 −6 meta-balena-common/recipes-core/systemd/systemd/resin_update_state_probe
+3 −0 meta-balena-common/recipes-core/systemd/systemd_%.bbappend
+20 −0 meta-balena-common/recipes-kernel/linux-firmware/linux-firmware_%.bbappend
+2 −0 meta-balena-common/recipes-support/balena-config-vars/balena-config-vars/balena-config-vars
+4 −0 meta-balena-common/recipes-support/balena-units-conf/balena-units-conf/unit-conf.json
+4 −2 meta-balena-common/recipes-support/hostapp-update-hooks/files/0-signed-update
+4 −0 meta-balena-common/recipes-support/hostapp-update-hooks/files/95-secureboot/2-fwd_commit_update-policy
+4 −0 meta-balena-common/recipes-support/hostapp-update-hooks/files/99-balena-bootloader
+3 −2 meta-balena-common/recipes-support/hostapp-update-hooks/files/99-resin-grub
+3 −2 meta-balena-common/recipes-support/hostapp-update-hooks/files/99-resin-uboot
+37 −0 meta-balena-common/recipes-support/os-fan-profile/os-fan-profile.bb
+13 −0 meta-balena-common/recipes-support/os-fan-profile/os-fan-profile/os-fan-profile
+15 −0 meta-balena-common/recipes-support/os-fan-profile/os-fan-profile/os-fan-profile.service
+5 −3 meta-balena-common/recipes-support/os-helpers/os-helpers/os-helpers-efi
+133 −0 meta-balena-common/recipes-support/os-helpers/os-helpers/os-helpers-fs
+37 −0 meta-balena-common/recipes-support/os-power-mode/os-power-mode.bb
+13 −0 meta-balena-common/recipes-support/os-power-mode/os-power-mode/os-power-mode
+15 −0 meta-balena-common/recipes-support/os-power-mode/os-power-mode/os-power-mode.service
+5 −0 meta-balena-common/recipes-support/resin-init/resin-init-flasher/balena-init-flasher-tpm
+30 −13 meta-balena-common/recipes-support/resin-init/resin-init-flasher/resin-init-flasher
+12 −5 meta-balena-common/recipes-support/resin-mounts/resin-mounts.bb
+3 −4 meta-balena-common/recipes-support/resin-mounts/resin-mounts/balena-nonencboot.service
+1 −1 tests/leviathan
+10 −9 tests/suites/hup/suite.js
+477 −258 tests/suites/os/package-lock.json
+1 −0 tests/suites/os/package.json
+1 −0 tests/suites/os/suite.js
+68 −0 tests/suites/os/tests/power-and-cooling/assets/helpers.sh
+81 −0 tests/suites/os/tests/power-and-cooling/index.js
+142 −19 tests/suites/os/tests/secureboot/index.js
+13 −1 tests/suites/os/tests/udev/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/bin/sh

. /usr/libexec/os-helpers-fs
. /usr/libexec/os-helpers-logging

set -o errexit

Expand All @@ -13,11 +14,6 @@ OFFS=(1659 5243 18043)
BOOT_BLOB="${BIN_INSTALL_PATH}/boot0.img"
DURING_UPDATE=${DURING_UPDATE:-0}

info_log()
{
echo "[INFO] $@"
}

# Old 28.x based images are not able to re-write the
# 28.x L4T partition layout with the offsets expected
# by the tegra firmware at that revision. We therefore
Expand All @@ -29,20 +25,20 @@ backport_rollback_health_fix()
# On 32.x releases this file was renamed, there's no need to update it
if [ -e ${inactive_hook} ]; then
if grep -q "DURING_UPDATE" "${inactive_hook}"; then
info_log "No need to backport rollback-health fix to old hook"
info "No need to backport rollback-health fix to old hook"
else
# Extra check, new 32.X systems use a different name for the partition spec file
old_part_spec=$(find /mnt/sysroot/active/ -name "partition_specification.txt")
if [ -e ${old_part_spec} ]; then
info_log "Will backport rollback-health fix to old hostapp-update hook"
info "Will backport rollback-health fix to old hostapp-update hook"
cp "${BIN_INSTALL_PATH}/tx2_28_x_hook_fix.sh" ${inactive_hook}
info_log "Applied rollback-health fix to old hostapp-update hook"
info "Applied rollback-health fix to old hostapp-update hook"
else
info_log "Old partition specification file not found in current sysroot: ${old_part_spec}, hook will not be replaced!"
info "Old partition specification file not found in current sysroot: ${old_part_spec}, hook will not be replaced!"
fi
fi
else
info_log "Upgrading from an L4T 32.X system, rollback-health fix is not needed"
info "Upgrading from an L4T 32.X system, rollback-health fix is not needed"
fi
}

Expand All @@ -53,7 +49,7 @@ update_needed() {
update_size=$(ls -al $current_update_file | awk '{print $5}')
update_md5sum=$(md5sum $current_update_file | awk '{print $1'})

existing_md5sum=$(dd if=$device bs=1 count=$update_size status=none | md5sum | awk '{print $1}')
existing_md5sum=$(dd if=$device count=1 bs=$update_size status=none | md5sum | awk '{print $1}')

if [ ! "$existing_md5sum" = "$update_md5sum" ]; then
echo 1
Expand All @@ -77,8 +73,8 @@ get_odm_value() {
set_odm_value() {
for offset in ${OFFS[@]}
do
info_log "Writing ODM byte ${1} to ${2} at offset ${offset}"
echo -n -e "\\x${1}" | dd of=${2} seek=${offset} bs=1 count=1 conv=notrunc
info "Writing ODM byte ${1} to ${2} at offset ${offset}"
echo -n -e "\\x${1}" | dd of=${2} seek=${offset} bs=1 count=1 conv=notrunc,fsync
done
}

Expand Down Expand Up @@ -114,39 +110,39 @@ update_partition_binaries()
# any units running on 28.x should have been upgraded, and even so, we do backport_rollback_health_fix()
while [ ! -L "$dst" ]
do
info_log "Symlink $dst for $part_name not found, will retry in a second..."
info "Symlink $dst for $part_name not found, will retry in a second..."
sleep 1;
retries=$(( $retries + 1 ))
if [ $retries -ge $max_retries ]; then
info_log "Retries limit reached and $dst is still not present, bail out!"
info "Retries limit reached and $dst is still not present, bail out!"
exit 1
fi
dst=$(get_state_path_from_label "$part_name")
info_log "State path after retry is $dst"
info "State path after retry is $dst"
done

if [ $(update_needed $src $dst) -eq 1 ]; then
info_log "Will update ${dst}"
dd if=${src} of=${dst} bs=1K
info_log "Updated ${dst}"
info "Will update ${dst}"
dd if=${src} of=${dst} bs=64K conv=fsync
info "Updated ${dst}"
else
info_log "No need to update ${dst}"
info "No need to update ${dst}"
fi
done
}

NUM_ADSP_PART=$(parted -s ${DEV_PATH} print | grep adsp | wc -l)
if [ ${NUM_ADSP_PART} -lt 2 ]; then
# adsp-fw partitions are mandatory only on L4T 32.2
info_log "ADSP firmware partition NOT found:${NUM_ADSP_PART}. Will upgrade partition table to L4T 32.2"
info "ADSP firmware partition NOT found:${NUM_ADSP_PART}. Will upgrade partition table to L4T 32.2"
UPGRADE_PARTITIONS=1
else
info_log "Found ${NUM_ADSP_PART} ADSP firmware partitions. No need to upgrade GPT"
info "Found ${NUM_ADSP_PART} ADSP firmware partitions. No need to upgrade GPT"
fi

if [ ${UPGRADE_PARTITIONS} -eq 1 ]; then
backport_rollback_health_fix
info_log "Removing old L4T 28.X partitions"
info "Removing old L4T 28.X partitions"

num_parts=$(sfdisk -l /dev/mmcblk0 | grep mmcblk0p | wc -l)
for (( idx=1; idx <= ${num_parts}; ++idx ))
Expand All @@ -158,7 +154,7 @@ if [ ${UPGRADE_PARTITIONS} -eq 1 ]; then
fi
done

info_log "Proceeding to create new L4T partitions"
info "Proceeding to create new L4T partitions"

# If the partition table was rolled-back to 28.X due to rollback-health,
# we first need to set the new (32.X) number of partitions in the MBR
Expand All @@ -173,11 +169,11 @@ if [ ${UPGRADE_PARTITIONS} -eq 1 ]; then
part_size=$(echo $n | cut -d ':' -f 3)
end=$(expr ${start} \+ ${part_size} \- 1)
parted -s ${DEV_PATH} unit s mkpart $part_name ${start} ${end}
dd if="${BIN_INSTALL_PATH}/${file_name}" of=${DEV_PATH} conv=notrunc seek=${start}
dd if="${BIN_INSTALL_PATH}/${file_name}" of=${DEV_PATH} conv=notrunc seek=${start} conv=fsync
start=$(expr ${end} \+ 1)
done

info_log "Created L4T 32.X partitions"
info "Created L4T 32.X partitions"

elif [ ${UPGRADE_PARTITIONS} -eq 0 ]; then
update_partition_binaries "${BIN_INSTALL_PATH}/partition_specification186.txt"
Expand All @@ -187,11 +183,11 @@ bootpart_odm=$(get_odm_value ${BOOT_PART});
bootblob_odm=$(get_odm_value ${BOOT_BLOB});

if [[ ${bootpart_odm} != "unmatched"} ]] && [[ ${bootblob_odm} != "unmatched" ]] ; then
info_log "Valid ODMDATA values found in both ${BOOT_PART} and ${BOOT_BLOB}"
info "Valid ODMDATA values found in both ${BOOT_PART} and ${BOOT_BLOB}"
if [[ ${bootpart_odm} == ${bootblob_odm} ]]; then
info_log "No need to transfer existing ODMDATA"
info "No need to transfer existing ODMDATA"
else
info_log "Existing ODMDATA ${bootpart_odm} does not match HUP ODMDATA ${bootblob_odm}"
info "Existing ODMDATA ${bootpart_odm} does not match HUP ODMDATA ${bootblob_odm}"
set_odm_value ${bootpart_odm} ${BOOT_BLOB}
fi;
else
Expand All @@ -202,13 +198,14 @@ src=${BOOT_BLOB}
dst=${BOOT_PART}

if [ $(update_needed $src $dst) -eq 1 ]; then
info_log "Will update $dst"
info "Will update $dst"
echo 0 > /sys/block/mmcblk0boot0/force_ro
dd if=${src} of=${dst} bs=1K
# 64K block size gives optimal performance, larger values show no speed-up
dd if=${src} of=${dst} bs=64K conv=fsync
echo 1 > /sys/block/mmcblk0boot0/force_ro
info_log "Updated $dst"
info "Updated $dst"
else
info_log "No need to update ${dst}"
info "No need to update ${dst}"
fi

sync
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@
set -o errexit

. /usr/libexec/os-helpers-fs
. /usr/libexec/os-helpers-logging

QSPI="/dev/mtd0"
BOOTLOADER_DEVICE="/dev/mtdblock0"

info_log()
{
echo "[INFO] $@"
}

# Jetson Nano SD has a qspi-nor,
# Jetson Nano eMMC doesn't.
if [ ! -e "${BOOTLOADER_DEVICE}" ]; then
info_log "This Nano module does not have a QSPI NOR, using hardware partition for boot blob"
info "This Nano module does not have a QSPI NOR, using hardware partition for boot blob"
BOOTLOADER_DEVICE="/dev/mmcblk0boot0"
fi

Expand Down Expand Up @@ -52,26 +48,26 @@ for n in ${partitions}; do
dst="$file_path"

if [ $(update_needed $src $dst) -eq 1 ]; then
info_log "Will update ${dst}..."
dd if=${src} of=${dst}
info "Will update ${dst}..."
dd if=${src} of=${dst} bs=64K conv=fsync
else
info_log "No need to update ${dst}"
info "No need to update ${dst}"
fi
done

existing_bootloader_md5sum=$(dd if=${BOOTLOADER_DEVICE} bs=1M status=none | md5sum | awk '{print $1}')
update_bootloader_md5sum=$(md5sum ${BOOT_BLOB} | awk '{print $1}')

if [ ! "$existing_bootloader_md5sum" = "$update_bootloader_md5sum" ]; then
info_log "Will update bootloader device ${BOOTLOADER_DEVICE}"
info "Will update bootloader device ${BOOTLOADER_DEVICE}"
if [ -e "${QSPI}" ]; then
flash_erase ${QSPI} 0 0 || true
else
echo 0 > /sys/block/mmcblk0boot0/force_ro
fi
dd if=${BOOT_BLOB} of=${BOOTLOADER_DEVICE} bs=1M || true
dd if=${BOOT_BLOB} of=${BOOTLOADER_DEVICE} bs=1M conv=fsync
else
info_log "No need to update bootloader device"
info "No need to update bootloader device"
fi

sync
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,34 @@ set -o errexit
# the rest of the bootloader binaries

. /usr/libexec/os-helpers-fs
. /usr/libexec/os-helpers-logging

DURING_UPDATE=${DURING_UPDATE:-0}
bootloader_device="/dev/mmcblk0boot0"
partspec="/resin-boot/bootfiles/partition_specification194.txt"
bootloader_blob="/resin-boot/bootfiles/boot0_t194.bin.gz"
bootpart_kernel="/mnt/boot/bootfiles/boot_sigheader.img.encrypt"

info_log()
{
echo "[INFO] $@"
}

# Check if old release made use of
# DURING_UPDATE flag and backport rollback-altboot
# fix to old hook if necessary.
backport_rollback_altboot_fix()
{
inactive_hook=$(find /mnt/sysroot/active/ | grep "99-resin-bootfiles-xavier")
if grep -q "DURING_UPDATE" "${inactive_hook}"; then
info_log "No need to backport altboot fix to old hook"
info "No need to backport altboot fix to old hook"
else
info_log "Will backport rollback-altboot fix to old hook"
info "Will backport rollback-altboot fix to old hook"
sed -i 's/os-helpers-fs/os-helpers-fs \nDURING_UPDATE=${DURING_UPDATE:-0}\nif [ "$DURING_UPDATE" = "0" ]; then target_sysroot="active"; else target_sysroot="inactive"; fi; /g' ${inactive_hook}
sed -i 's|/mnt/sysroot/inactive|/mnt/sysroot/${target_sysroot}|g' ${inactive_hook}
info_log "Applied rollback-altboot fix to old hostapp-update hook"
info "Applied rollback-altboot fix to old hostapp-update hook"
fi

if [ -e ${bootpart_kernel} ]; then
rm ${bootpart_kernel}
info_log "Removed signed kernel binary from boot partition, it is now located in the rootfs"
info "Removed signed kernel binary from boot partition, it is now located in the rootfs"
else
info_log "No need to remove kernel binary from boot partition"
info "No need to remove kernel binary from boot partition"
fi
}

Expand All @@ -53,29 +49,29 @@ get_label_suffix_by_slot()

if ! command -v tegra-boot-control &> /dev/null
then
info_log "Could not find tegra-boot-control!"
info "Could not find tegra-boot-control!"
exit 1
fi

redundancy_state=$(/usr/bin/tegra-boot-control -s | awk -F 'Redundancy:' '{print $2}' | awk '{print $1}' | tr -d '\n')
info_log "Redundancy is currently ${redundancy_state}"
info "Redundancy is currently ${redundancy_state}"

# Enable boot slot redundancy if not enabled already
tegra-boot-control -e
curr_slot=$(/usr/bin/tegra-boot-control -c)
info_log "Current active slot is ${curr_slot}"
info "Current active slot is ${curr_slot}"

if [ "$DURING_UPDATE" = "1" ]; then
backport_rollback_altboot_fix
info_log "Target active slot is $((target_slot = ! curr_slot))"
info "Target active slot is $((target_slot = ! curr_slot))"
target_sysroot="inactive"
else
info_log "Target active slot stays $((target_slot = curr_slot))"
info "Target active slot stays $((target_slot = curr_slot))"
target_sysroot="active"
fi

target_part=$(findmnt --noheadings --canonicalize --output SOURCE "/mnt/sysroot/${target_sysroot}" -t ext4)
info_log "New rootfs partition is ${target_part}"
info "New rootfs partition is ${target_part}"

target_label_suffix=$(get_label_suffix_by_slot ${target_slot})
rootstr=$(get_dev_label "${target_part}")
Expand Down Expand Up @@ -107,7 +103,7 @@ case "$rootstr" in
;;
esac

info_log "New root is resin-root${rootl}"
info "New root is resin-root${rootl}"

dtbname=$(cat "$partspec" | grep "kernel-dtb_b" | cut -d ':' -f 2 | awk -F'_sigheader' '{print $1}')
dtbfile="${dtbname}-root${rootl}_sigheader.dtb.encrypt"
Expand Down Expand Up @@ -139,50 +135,51 @@ for n in ${partitions}; do
src="/resin-boot/bootfiles/$file_name"
if [ -e ${dst} ]; then
if [ $(update_needed $src $dst) -eq 1 ]; then
info_log "Will update ${dst} ..."
dd if=${src} of="${dst}"
info_log "Updated ${dst}"
info "Will update ${dst} ..."
dd if=${src} of="${dst}" bs=64K conv=fsync
info "Updated ${dst}"
else
info_log "No need to update ${dst}"
info "No need to update ${dst}"
fi
else
info_log "Partition ${dst} not found"
info "Partition ${dst} not found"
fi
done

# DTB contains root partition label, update is mandatory on the new boot slot, before switching it to active
info_log "Writing ${dtbfile} to specific to bootloader-dtb partition."
dd if=/resin-boot/bootfiles/${dtbfile} of=$(get_state_path_from_label "bootloader-dtb")
info "Writing ${dtbfile} to specific to bootloader-dtb partition."
dd if=/resin-boot/bootfiles/${dtbfile} of=$(get_state_path_from_label "bootloader-dtb") bs=64K conv=fsync

info_log "Writing ${dtbfile} to specific to bootloader-dtb_b partition."
dd if=/resin-boot/bootfiles/${dtbfile} of=$(get_state_path_from_label "bootloader-dtb_b")
info "Writing ${dtbfile} to specific to bootloader-dtb_b partition."
dd if=/resin-boot/bootfiles/${dtbfile} of=$(get_state_path_from_label "bootloader-dtb_b") bs=64K conv=fsync

dd if=/resin-boot/bootfiles/${dtbfile} of=$(get_state_path_from_label "kernel-dtb${target_label_suffix}")
dd if=/resin-boot/bootfiles/${dtbfile} of=$(get_state_path_from_label "kernel-dtb${target_label_suffix}") bs=64K conv=fsync

info_log "Writing kernel ${kernel} to specific partitions..."
info "Writing kernel ${kernel} to specific partitions..."

dd if=/opt/tegra-binaries/${kernel} of=$(get_state_path_from_label "kernel${target_label_suffix}")
info_log "Updating boot image on hw partition mmcblk0boot0..."
dd if=/opt/tegra-binaries/${kernel} of=$(get_state_path_from_label "kernel${target_label_suffix}") bs=64K conv=fsync
info "Updating boot image on hw partition mmcblk0boot0..."

existing_bootloader_md5sum=$(dd if=$bootloader_device bs=1M status=none | md5sum | awk '{print $1}')
update_bootloader_md5sum=$(zcat $bootloader_blob | md5sum | awk '{print $1}')

if [ ! "$existing_bootloader_md5sum" = "$update_bootloader_md5sum" ]; then
echo 0 > /sys/block/mmcblk0boot0/force_ro
zcat $bootloader_blob > $bootloader_device
sync
zcat $bootloader_blob | dd of=$bootloader_device bs=64K conv=fsync
echo 1 > /sys/block/mmcblk0boot0/force_ro
fi

# Update slot selection after the qspi was updated, otherwise
# scratch register contents will be lost
info_log "Setting active slot to ${target_slot}"
info "Setting active slot to ${target_slot}"
/usr/bin/tegra-boot-control -e
/usr/bin/tegra-boot-control -a ${target_slot}

if [ "$DURING_UPDATE" = "0" ]; then
/usr/bin/tegra-boot-control -m
info_log "Running in rollback-altboot, next boot will be from the same slot. Marked boot as successful."
info "Running in rollback-altboot, next boot will be from the same slot. Marked boot as successful."
fi

info_log "Done."
info "Done."

sync
Loading
Loading