1#!/bin/bash 2set -eo pipefail 3 4# Get the root mtd device number (mtdX) from "/dev/ubiblockX_Y on /" 5findrootmtd() { 6 rootmatch=" on / " 7 m="$(mount | grep "${rootmatch}" | grep "ubiblock")" 8 m="${m##*ubiblock}" 9 m="${m%_*}" 10 if [ -z "${m}" ]; then 11 # default to bmc mtd (0) 12 m=0 13 fi 14 echo "mtd${m}" 15} 16 17findrootubi() { 18 rootmatch=" on / " 19 m="$(mount | grep "${rootmatch}")" 20 m="${m##*ubiblock}" 21 m="${m% on*}" 22 echo "ubi${m}" 23} 24 25# Get the mtd device number (mtdX) 26findmtd() { 27 m="$(grep -xl "$1" /sys/class/mtd/*/name)" 28 m="${m%/name}" 29 m="${m##*/}" 30 echo "${m}" 31} 32 33# Get the mtd device number only (return X of mtdX) 34findmtdnum() { 35 m="$(findmtd "$1")" 36 m="${m##mtd}" 37 echo "${m}" 38} 39 40# Get the ubi device number (ubiX_Y) 41findubi() { 42 u="$(grep -xl "$1" /sys/class/ubi/ubi?/subsystem/ubi*/name)" 43 u="${u%/name}" 44 u="${u##*/}" 45 echo "${u}" 46} 47 48# Get the ubi device number (ubiX_Y) on a specific mtd 49findubi_onmtd() { 50 u="$(grep -xl "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)" 51 u="${u%/name}" 52 u="${u##*/}" 53 echo "${u}" 54} 55 56# Get all ubi device names on a specific mtd that match requested string 57findubiname_onmtd() { 58 u="$(grep -h "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)" 59 u="${u%/name}" 60 u="${u##*/}" 61 echo "${u}" 62} 63 64# Get the name from the requested ubiX_Y volume 65findname() { 66 n="$(cat /sys/class/ubi/$1/name)" 67 echo "${n}" 68} 69 70# Set the version path property to the flash location where the image was 71# successfully flashed 72set_flashid() { 73 busctl set-property xyz.openbmc_project.Software.BMC.Updater \ 74 "/xyz/openbmc_project/software/${version}" \ 75 xyz.openbmc_project.Common.FilePath \ 76 Path s "$1" 77} 78 79# Set the u-boot envs that perform a side switch on failure to boot 80set_wdt2bite() { 81 if ! fw_printenv wdt2bite 2>/dev/null; then 82 fw_setenv wdt2bite "mw.l 0x1e785024 0xa 1; mw.b 0x1e78502c 0xb3 1" 83 fw_setenv bootalt "run wdt2bite" 84 fw_setenv obmc_bootcmd "ubi part obmc-ubi; run do_rwreset; ubi read \ 85\${loadaddr} \${kernelname}; bootm \${loadaddr} || run bootalt" 86 fi 87} 88 89# Make space on flash before creating new volumes. This can be enhanced 90# determine current flash usage. For now only keep a "keepmax" number of them 91ubi_remove_volumes() 92{ 93 rootubi="$(findrootubi)" 94 rootname="$(findname "${rootubi}")" 95 rootversion="${rootname##*-}" 96 rootkernel="kernel-${rootversion}" 97 98 # Just keep max number of volumes before updating, don't delete the version 99 # the BMC is booted from, and when a version is identified to be deleted, 100 # delete both the rofs and kernel volumes for that version. 101 rmnames="$(findubiname_onmtd "${name%-*}-" "${ro}")" 102 rmnames=(${rmnames}) 103 ubicount="${#rmnames[@]}" 104 while [ ${ubicount} -ge ${keepmax} ]; do 105 # Loop through existing volumes and skip currently active ones 106 for (( index=0; index<${#rmnames[@]}; index++ )); do 107 rmname="${rmnames[${index}]}" 108 rmversion="${rmname##*-}" 109 [ "${rmversion}" == "${version}" ] && continue 110 rmubi="$(findubi_onmtd "rofs-${rmversion}" "${ro}")" 111 if [[ ( "${rmubi}" != "${rootubi}" ) && 112 ( "${rmname}" != "${rootkernel}" ) ]]; then 113 ubi_remove "rofs-${rmversion}" "${ro}" 114 ubi_remove "kernel-${rmversion}" "${ro}" 115 # Remove priority value 116 fw_setenv "${rmversion}" 117 break 118 fi 119 done 120 # Decrease count regardless to avoid an infinite loop 121 (( ubicount-- )) 122 done 123} 124 125ubi_rw() { 126 rwmtd="$(findmtd "${reqmtd}")" 127 rw="${rwmtd#mtd}" 128 ubidev="/dev/ubi${rw}" 129 130 # Update rwfs_size, check imgsize was specified, otherwise it'd clear the var 131 if [ ! -z "$imgsize" ]; then 132 rwsize="$(fw_printenv -n rwfs_size 2>/dev/null)" || true 133 if [[ "${imgsize}" != "${rwsize}" ]]; then 134 fw_setenv rwfs_size "${imgsize}" 135 fi 136 fi 137 138 vol="$(findubi "${name}")" 139 if [ -z "${vol}" ]; then 140 ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}" 141 fi 142} 143 144ubi_ro() { 145 keepmax=2 # Default 2 volumes per mtd 146 romtd="$(findmtd "${reqmtd}")" 147 romtd2="$(findmtd "${reqmtd2}")" 148 149 if [ ! "${romtd}" == "${romtd2}" ]; then 150 # Request to use alternate mtd device, choose the non-root one 151 keepmax=1 # 1 volume on each of the requested mtds 152 rootmtd="$(findrootmtd)" 153 if [ "${rootmtd}" == "${romtd}" ]; then 154 romtd="${romtd2}" 155 fi 156 fi 157 ro="${romtd#mtd}" 158 ubidev="/dev/ubi${ro}" 159 160 ubi_remove_volumes 161 162 if [ -z "${imgfile}" ]; then 163 echo "Unable to create read-only volume. Image file not specified." 164 return 1 165 fi 166 167 # Create a ubi volume, dynamically sized to fit BMC image if size unspecified 168 img="/tmp/images/${version}/${imgfile}" 169 imgsize="$(stat -c '%s' ${img})" 170 171 vol="$(findubi "${name}")" 172 if [ ! -z "${vol}" ]; then 173 # Allow a duplicate kernel volume on the alt mtd 174 if [[ "${name}" =~ "kernel" ]]; then 175 vol="$(findubi_onmtd "${name}" "${ro}")" 176 fi 177 fi 178 if [ -z "${vol}" ]; then 179 ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}" --type=static 180 vol="$(findubi "${name}")" 181 fi 182 183 set_flashid "${version}" 184} 185 186# Squashfs images need a ubi block 187ubi_block() { 188 vol="$(findubi "${name}")" 189 ubidevid="${vol#ubi}" 190 block="/dev/ubiblock${ubidevid}" 191 if [ ! -e "$block" ]; then 192 ubiblock --create "/dev/ubi${ubidevid}" 193 fi 194} 195 196ubi_updatevol() { 197 vol="$(findubi "${name}")" 198 ubidevid="${vol#ubi}" 199 img="/tmp/images/${version}/${imgfile}" 200 ubiupdatevol "/dev/ubi${ubidevid}" "${img}" 201} 202 203ubi_remove() { 204 rmname="$1" 205 rmmtd="$2" 206 if [ ! -z "${rmmtd}" ]; then 207 vol="$(findubi_onmtd "${rmname}" "${rmmtd}")" 208 else 209 vol="$(findubi "${rmname}")" 210 fi 211 212 if [ ! -z "$vol" ]; then 213 vol="${vol%_*}" 214 215 if grep -q "$rmname" /proc/mounts; then 216 mountdir=$(grep "$rmname" /proc/mounts | cut -d " " -f 2) 217 umount "$mountdir" 218 rm -r "$mountdir" 219 fi 220 221 ubirmvol "/dev/${vol}" -N "$rmname" 222 fi 223} 224 225ubi_cleanup() { 226 # When ubi_cleanup is run, it expects one or no active version. 227 activeVersion=$(busctl --list --no-pager tree \ 228 xyz.openbmc_project.Software.BMC.Updater | \ 229 grep /xyz/openbmc_project/software/ | tail -c 9) 230 231 if [[ -z "$activeVersion" ]]; then 232 vols=$(ubinfo -a | grep "rofs-" | cut -c 14-) 233 vols=(${vols}) 234 else 235 vols=$(ubinfo -a | grep "rofs-" | \ 236 grep -v "$activeVersion" | cut -c 14-) 237 vols=(${vols}) 238 fi 239 240 for (( index=0; index<${#vols[@]}; index++ )); do 241 ubi_remove ${vols[index]} 242 done 243} 244 245mount_alt_rwfs() { 246 altNum="$(findmtdnum "alt-bmc")" 247 if [ ! -z "${altNum}" ]; then 248 altRwfs=$(ubinfo -a -d ${altNum} | grep -w "rwfs") || true 249 if [ ! -z "${altRwfs}" ]; then 250 altVarMount="/media/alt/var" 251 mkdir -p "${altVarMount}" 252 if mount ubi"${altNum}":rwfs "${altVarMount}" -t ubifs -o defaults; then 253 mkdir -p "${altVarMount}"/persist/etc 254 fi 255 fi 256 fi 257} 258 259remount_ubi() { 260 bmcmtd="$(findmtd "bmc")" 261 altbmcmtd="$(findmtd "alt-bmc")" 262 mtds="${bmcmtd: -1}","${altbmcmtd: -1}" 263 264 IFS=',' read -r -a mtds <<< "$mtds" 265 mtds=($(echo "${mtds[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) 266 for mtd in ${mtds[@]}; do 267 # Get information on all ubi volumes 268 ubinfo=$(ubinfo -d ${mtd}) 269 presentVolumes=${ubinfo##*:} 270 IFS=', ' read -r -a array <<< "$presentVolumes" 271 for element in ${array[@]}; do 272 elementProperties=$(ubinfo -d $mtd -n $element) 273 # Get ubi volume name by getting rid of additional properties 274 name=${elementProperties#*Name:} 275 name="${name%Character*}" 276 name="$(echo -e "${name}" | tr -d '[:space:]')" 277 278 if [[ ${name} == rofs-* ]]; then 279 mountdir="/media/${name}" 280 281 if [ ! -d ${mountdir} ]; then 282 mkdir -p "${mountdir}" 283 # U-Boot will create the ubiblock for the running version, but not 284 # for the version on the other chip 285 if [ ! -e "/dev/ubiblock${mtd}_${element}" ]; then 286 ubiblock --create /dev/ubi${mtd}_${element} 287 fi 288 mount -t squashfs -o ro "/dev/ubiblock${mtd}_${element}" "${mountdir}" 289 fi 290 fi 291 done 292 done 293 294 set_wdt2bite 295} 296 297# Read the current env variable and set it on the alternate boot env 298copy_env_var_to_alt() { 299 varName=$1 300 value="$(fw_printenv -n "${varName}")" 301 fw_setenv -c /etc/alt_fw_env.config "${varName}" "${value}" 302} 303 304# When the alternate bmc chip boots, u-boot thinks its the primary mtdX. 305# Therefore need to swap the chip numbers when copying the ubiblock and root to 306# alternate bmc u-boot environment. 307copy_ubiblock_to_alt() { 308 value="$(fw_printenv -n ubiblock)" 309 bmcNum="$(findmtdnum "bmc")" 310 altNum="$(findmtdnum "alt-bmc")" 311 replaceAlt="${value/${altNum},/${bmcNum},}" 312 313 if [[ "${value}" == "${replaceAlt}" ]]; then 314 replaceBmc="${value/${bmcNum},/${altNum},}" 315 value=${replaceBmc} 316 else 317 value=${replaceAlt} 318 fi 319 320 fw_setenv -c /etc/alt_fw_env.config ubiblock "${value}" 321} 322 323copy_root_to_alt() { 324 value="$(fw_printenv -n root)" 325 bmcNum="$(findmtdnum "bmc")" 326 altNum="$(findmtdnum "alt-bmc")" 327 replaceAlt="${value/${altNum}_/${bmcNum}_}" 328 329 if [[ "${value}" == "${replaceAlt}" ]]; then 330 replaceBmc="${value/${bmcNum}_/${altNum}_}" 331 value=${replaceBmc} 332 else 333 value=${replaceAlt} 334 fi 335 336 fw_setenv -c /etc/alt_fw_env.config root "${value}" 337} 338 339ubi_setenv() { 340 # The U-Boot environment maintains two banks of environment variables. 341 # The banks need to be consistent with each other to ensure that these 342 # variables can reliably be read from file. In order to guarantee that the 343 # banks are both correct, we need to run fw_setenv twice. 344 variable=$1 345 if [[ "$variable" == *"="* ]]; then 346 varName="${variable%=*}" 347 value="${variable##*=}" 348 # Write only if var is not set already to the requested value 349 currentValue="$(fw_printenv -n "${varName}" 2>/dev/null)" || true 350 if [[ "${currenValue}" != "${value}" ]]; then 351 fw_setenv "$varName" "$value" 352 fw_setenv "$varName" "$value" 353 fi 354 else 355 fw_setenv "$variable" 356 fw_setenv "$variable" 357 fi 358} 359 360mtd_write() { 361 flashmtd="$(findmtd "${reqmtd}")" 362 img="/tmp/images/${version}/${imgfile}" 363 flashcp -v ${img} /dev/${flashmtd} 364} 365 366backup_env_vars() { 367 copy_env_var_to_alt kernelname 368 copy_ubiblock_to_alt 369 copy_root_to_alt 370} 371 372update_env_vars() { 373 vol="$(findubi rofs-"${version}")" 374 if [ -z "${vol}" ]; then 375 return 1 376 fi 377 ubidevid="${vol#ubi}" 378 block="/dev/ubiblock${ubidevid}" 379 if [ ! -e "${block}" ]; then 380 return 1 381 fi 382 ubi_setenv "kernelname=kernel-${version}" 383 ubi_setenv "ubiblock=$(echo "${ubidevid}" | sed 's/_/,/')" 384 ubi_setenv "root=${block}" 385} 386 387#TODO: Replace the implementation with systemd-inhibitors lock 388# once systemd/systemd#949 is resolved 389rebootguardenable() { 390 dir="/run/systemd/system/" 391 file="reboot-guard.conf" 392 units=("reboot" "poweroff" "halt") 393 394 for unit in "${units[@]}"; do 395 mkdir -p ${dir}${unit}.target.d 396 echo -e "[Unit]\nRefuseManualStart=yes" >> ${dir}${unit}.target.d/${file} 397 done 398} 399 400#TODO: Replace the implementation with systemd-inhibitors lock 401# once systemd/systemd#949 is resolved 402rebootguarddisable() { 403 dir="/run/systemd/system/" 404 file="reboot-guard.conf" 405 units=("reboot" "poweroff" "halt") 406 407 for unit in "${units[@]}"; do 408 rm -rf ${dir}${unit}.target.d/${file} 409 done 410} 411 412# Create a copy in the alt mtd 413create_vol_in_alt() { 414 alt="alt-bmc" 415 altmtd="$(findmtd "${alt}")" 416 if [ ! -z "${altmtd}" ]; then 417 reqmtd="${alt}" 418 reqmtd2="${alt}" 419 ubi_ro 420 ubi_updatevol 421 fi 422} 423 424# Copy contents of one MTD device to another 425mtd_copy() { 426 in=$1 427 out=$2 428 429 # Must erase MTD first to prevent corruption 430 flash_eraseall "${out}" 431 dd if="${in}" of="${out}" 432} 433 434mirroruboot() { 435 bmc="$(findmtd "u-boot")" 436 bmcdev="/dev/${bmc}" 437 alt="$(findmtd "alt-u-boot")" 438 altdev="/dev/${alt}" 439 440 checksum_bmc="$(md5sum "${bmcdev}")" 441 checksum_bmc="${checksum_bmc% *}" 442 checksum_alt="$(md5sum "${altdev}")" 443 checksum_alt="${checksum_alt% *}" 444 445 if [[ "${checksum_bmc}" != "${checksum_alt}" ]]; then 446 bmcenv="$(findmtd "u-boot-env")" 447 bmcenvdev="/dev/${bmcenv}" 448 altenv="$(findmtd "alt-u-boot-env")" 449 altenvdev="/dev/${altenv}" 450 451 echo "Mirroring U-boot to alt chip" 452 mtd_copy "${bmcdev}" "${altdev}" 453 mtd_copy "${bmcenvdev}" "${altenvdev}" 454 455 copy_ubiblock_to_alt 456 copy_root_to_alt 457 fi 458} 459 460# Compare the device where u-boot resides with an image file. Specify the full 461# path to the device and image file to use for the compare. Print a value of 462# "0" if identical, "1" otherwise. 463cmp_uboot() { 464 device="$1" 465 image="$2" 466 467 # Since the image file can be smaller than the device, copy the device to a 468 # tmp file and write the image file on top, then compare the sum of each. 469 # Use cat / redirection since busybox does not have the conv=notrunc option. 470 tmpFile="$(mktemp /tmp/ubootdev.XXXXXX)" 471 dd if="${device}" of="${tmpFile}" 472 devSum="$(sha256sum ${tmpFile})" 473 cat < "${image}" 1<> "${tmpFile}" 474 imgSum="$(sha256sum ${tmpFile})" 475 rm -f "${tmpFile}" 476 477 if [ "${imgSum}" == "${devSum}" ]; then 478 echo "0"; 479 else 480 echo "1"; 481 fi 482} 483 484# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b. 485# Return the label (a or b) for the running partition. 486mmc_get_primary_label() { 487 # Get root device /dev/mmcblkpX 488 rootmatch=" on / " 489 root="$(mount | grep "${rootmatch}")" 490 root="${root%${rootmatch}*}" 491 492 # Find the device label 493 if [[ $(readlink -f /dev/disk/by-partlabel/rofs-a) == "${root}" ]]; then 494 echo "a" 495 elif [[ $(readlink -f /dev/disk/by-partlabel/rofs-b) == "${root}" ]]; then 496 echo "b" 497 else 498 echo "" 499 fi 500} 501 502# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b. 503# Return the label (a or b) for the non-running partition. 504mmc_get_secondary_label() { 505 root="$(mmc_get_primary_label)" 506 if [[ "${root}" == "a" ]]; then 507 echo "b" 508 elif [[ "${root}" == "b" ]]; then 509 echo "a" 510 else 511 echo "" 512 fi 513} 514 515mmc_update() { 516 # Update u-boot if needed 517 bootPartition="mmcblk0boot0" 518 devUBoot="/dev/${bootPartition}" 519 imgUBoot="${imgpath}/${version}/image-u-boot" 520 if [ "$(cmp_uboot "${devUBoot}" "${imgUBoot}")" != "0" ]; then 521 echo 0 > "/sys/block/${bootPartition}/force_ro" 522 dd if="${imgUBoot}" of="${devUBoot}" 523 echo 1 > "/sys/block/${bootPartition}/force_ro" 524 fi 525 526 # Update the secondary (non-running) boot and rofs partitions. 527 label="$(mmc_get_secondary_label)" 528 529 # Update the boot and rootfs partitions, restore their labels after the update 530 # by getting the partition number mmcblk0pX from their label. 531 zstd -d -c ${imgpath}/${version}/image-kernel | dd of="/dev/disk/by-partlabel/boot-${label}" 532 number="$(readlink -f /dev/disk/by-partlabel/boot-${label})" 533 number="${number##*mmcblk0p}" 534 sgdisk --change-name=${number}:boot-${label} /dev/mmcblk0 1>/dev/null 535 536 zstd -d -c ${imgpath}/${version}/image-rofs | dd of="/dev/disk/by-partlabel/rofs-${label}" 537 number="$(readlink -f /dev/disk/by-partlabel/rofs-${label})" 538 number="${number##*mmcblk0p}" 539 sgdisk --change-name=${number}:rofs-${label} /dev/mmcblk0 1>/dev/null 540 541 # Run this after sgdisk for labels to take effect. 542 partprobe 543 544 # Update hostfw 545 if [ -f ${imgpath}/${version}/image-hostfw ]; then 546 # Remove patches 547 patchdir="/usr/local/share/hostfw/alternate" 548 if [ -d "${patchdir}" ]; then 549 rm -rf "${patchdir}"/* 550 fi 551 hostfwdir=$(grep "hostfw " /proc/mounts | cut -d " " -f 2) 552 cp ${imgpath}/${version}/image-hostfw ${hostfwdir}/hostfw-${label} 553 mkdir -p ${hostfwdir}/alternate 554 mount ${hostfwdir}/hostfw-${label} ${hostfwdir}/alternate -o ro 555 fi 556 557 # Store the label where the other properties like purpose and priority are 558 # preserved via the storePriority() function in the serialize files, so that 559 # it can be used for the remove function. 560 label_dir="/var/lib/phosphor-bmc-code-mgmt/${version}" 561 label_file="${label_dir}/partlabel" 562 mkdir -p "${label_dir}" 563 echo "${label}" > "${label_file}" 564 565 set_flashid "${label}" 566} 567 568mmc_remove() { 569 # Render the filesystem unbootable by wiping out the first 1MB, this 570 # invalidates the filesystem header. 571 # If the label property does not exist, assume it's the secondary 572 # (non-running) one since the running device should not be erased. 573 label="" 574 label_file="/var/lib/phosphor-bmc-code-mgmt/${version}/partlabel" 575 if [ -f "${label_file}" ]; then 576 label="$(cat "${label_file}")" 577 else 578 label="$(mmc_get_secondary_label)" 579 fi 580 dd if=/dev/zero of=/dev/disk/by-partlabel/boot-${label} count=2048 581 dd if=/dev/zero of=/dev/disk/by-partlabel/rofs-${label} count=2048 582 583 hostfw_alt="hostfw/alternate" 584 if grep -q "${hostfw_alt}" /proc/mounts; then 585 hostfw_alt=$(grep "${hostfw_alt}" /proc/mounts | cut -d " " -f 2) 586 umount "${hostfw_alt}" 587 fi 588 hostfw_base="hostfw " 589 if grep -q "${hostfw_base}" /proc/mounts; then 590 hostfw_base=$(grep "${hostfw_base}" /proc/mounts | cut -d " " -f 2) 591 rm -f ${hostfw_base}/hostfw-${label} 592 fi 593} 594 595# Set the requested version as primary for the BMC to boot from upon reboot. 596mmc_setprimary() { 597 # Point root to the label of the requested BMC rootfs. If the label property 598 # does not exist, determine if the requested version is functional or not. 599 label="" 600 label_file="/var/lib/phosphor-bmc-code-mgmt/${version}/partlabel" 601 if [ -f "${label_file}" ]; then 602 label="$(cat "${label_file}")" 603 else 604 functional="$(busctl call xyz.openbmc_project.ObjectMapper \ 605 /xyz/openbmc_project/software/functional \ 606 org.freedesktop.DBus.Properties Get ss \ 607 xyz.openbmc_project.Association endpoints)" 608 if [[ "${functional}" =~ "${version}" ]]; then 609 label="$(mmc_get_primary_label)" 610 else 611 label="$(mmc_get_secondary_label)" 612 fi 613 fi 614 fw_setenv bootside "${label}" 615} 616 617case "$1" in 618 mtduboot) 619 reqmtd="$2" 620 version="$3" 621 imgfile="image-u-boot" 622 mtd_write 623 ;; 624 ubirw) 625 reqmtd="$2" 626 name="$3" 627 imgsize="$4" 628 ubi_rw 629 ;; 630 ubiro) 631 reqmtd="$(echo "$2" | cut -d "+" -f 1)" 632 reqmtd2="$(echo "$2" | cut -d "+" -f 2)" 633 name="$3" 634 version="$4" 635 imgfile="image-rofs" 636 ubi_ro 637 ubi_updatevol 638 ubi_block 639 ;; 640 ubikernel) 641 reqmtd="$(echo "$2" | cut -d "+" -f 1)" 642 reqmtd2="$(echo "$2" | cut -d "+" -f 2)" 643 name="$3" 644 version="$4" 645 imgfile="image-kernel" 646 ubi_ro 647 ubi_updatevol 648 create_vol_in_alt 649 ;; 650 ubiremove) 651 name="$2" 652 ubi_remove "${name}" 653 ;; 654 ubicleanup) 655 ubi_cleanup 656 ;; 657 ubisetenv) 658 ubi_setenv "$2" 659 ;; 660 ubiremount) 661 remount_ubi 662 mount_alt_rwfs 663 ;; 664 createenvbackup) 665 backup_env_vars 666 ;; 667 updateubootvars) 668 version="$2" 669 update_env_vars 670 ;; 671 rebootguardenable) 672 rebootguardenable 673 ;; 674 rebootguarddisable) 675 rebootguarddisable 676 ;; 677 mirroruboot) 678 mirroruboot 679 ;; 680 mmc) 681 version="$2" 682 imgpath="$3" 683 mmc_update 684 ;; 685 mmc-remove) 686 version="$2" 687 mmc_remove 688 ;; 689 mmc-setprimary) 690 version="$2" 691 mmc_setprimary 692 ;; 693 *) 694 echo "Invalid argument" 695 exit 1 696 ;; 697esac 698