mmc: Update and remove functions for the kernel and rootfs
Add support for update and remove of eMMC images.
The code update tarball contains an image-kernel and image-rofs
files. These can be flashed directly to the eMMC partitions since
they're filesystem files compressed with zstd:
https://gerrit.openbmc-project.xyz/c/openbmc/meta-phosphor/+/30781
https://gerrit.openbmc-project.xyz/c/openbmc/meta-phosphor/+/34334
The image-rofs contains the BMC rootfs files, and the image-kernel
contains the fitImage file which is loaded by U-Boot.
Tested: Verified the non-running rofs and kernel partitions were updated.
Change-Id: Ic983dec1df389d56f11f12dc2e82589d1a2b9dcc
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/obmc-flash-bmc b/obmc-flash-bmc
index 0b1b16e..fec50d0 100644
--- a/obmc-flash-bmc
+++ b/obmc-flash-bmc
@@ -446,6 +446,62 @@
fi
}
+# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b.
+# Return the label (a or b) for the non-running partition.
+mmc_get_secondary_label() {
+ rootmatch=" on / "
+ root="$(mount -l | grep "${rootmatch}")"
+ if [[ "${root}" == *"rofs-a"* ]]; then
+ echo "b"
+ else
+ echo "a"
+ fi
+}
+
+mmc_update() {
+ # Update the secondary (non-running) boot and rofs partitions.
+ label="$(mmc_get_secondary_label)"
+
+ # Update the boot and rootfs partitions, restore their labels after the update
+ # by getting the partition number mmcblk0pX from their label.
+ zstd -d -c ${imgpath}/${version}/image-kernel | dd of="/dev/disk/by-partlabel/boot-${label}"
+ number="$(readlink -f /dev/disk/by-partlabel/boot-${label})"
+ number="${number##*mmcblk0p}"
+ sgdisk --change-name=${number}:boot-${label} /dev/mmcblk0 1>/dev/null
+
+ zstd -d -c ${imgpath}/${version}/image-rofs | dd of="/dev/disk/by-partlabel/rofs-${label}"
+ number="$(readlink -f /dev/disk/by-partlabel/rofs-${label})"
+ number="${number##*mmcblk0p}"
+ sgdisk --change-name=${number}:rofs-${label} /dev/mmcblk0 1>/dev/null
+
+ # Run this after sgdisk for labels to take effect.
+ partprobe
+
+ # Store the label where the other properties like purpose and priority are
+ # preserved via the storePriority() function in the serialize files, so that
+ # it can be used for the remove function.
+ label_dir="/var/lib/phosphor-bmc-code-mgmt/${version}"
+ label_file="${label_dir}/partlabel"
+ mkdir -p "${label_dir}"
+ echo "${label}" > "${label_file}"
+}
+
+mmc_remove() {
+ # Render the filesystem unbootable by wiping out the first 1MB, this
+ # invalidates the filesystem header.
+ # If the label property does not exist, assume it's the secondary
+ # (non-running) one since the running device should not be erased.
+ label=""
+ label_file="/var/lib/phosphor-bmc-code-mgmt/${version}/partlabel"
+ if [ -f "${label_file}" ]; then
+ label="$(cat "${label_file}")"
+ else
+ label="$(mmc_get_secondary_label)"
+ fi
+ dd if=/dev/zero of=/dev/disk/by-partlabel/boot-${label} count=2048
+ dd if=/dev/zero of=/dev/disk/by-partlabel/rofs-${label} count=2048
+}
+
case "$1" in
mtduboot)
reqmtd="$2"
@@ -509,6 +565,15 @@
mirroruboot)
mirroruboot
;;
+ mmc)
+ version="$2"
+ imgpath="$3"
+ mmc_update
+ ;;
+ mmc-remove)
+ version="$2"
+ mmc_remove
+ ;;
*)
echo "Invalid argument"
exit 1