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  mapfile -t array <<< "${rmnames}"
103  ubicount="${#array[@]}"
104  while [ "${ubicount}" -ge "${keepmax}" ]; do
105    # Loop through existing volumes and skip currently active ones
106    for (( index=0; index<${#array[@]}; index++ )); do
107      rmname="${array[${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 [ -n "$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 [ -n "${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 [ -n "${rmmtd}" ]; then
207      vol="$(findubi_onmtd "${rmname}" "${rmmtd}")"
208    else
209      vol="$(findubi "${rmname}")"
210    fi
211
212    if [ -n "$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    else
234        flashid=$(busctl get-property xyz.openbmc_project.Software.BMC.Updater \
235            "/xyz/openbmc_project/software/${activeVersion}" \
236            xyz.openbmc_project.Common.FilePath Path |  awk '{print $NF;}' | tr -d '"')
237        vols=$(ubinfo -a | grep "rofs-" | \
238                grep -v "$flashid" | cut -c 14-) || true
239    fi
240
241    mapfile -t array <<< "${vols}"
242    for (( index=0; index<${#array[@]}; index++ )); do
243         ubi_remove "${array[index]}"
244    done
245}
246
247mount_ubi_alt_rwfs() {
248  altNum="$(findmtdnum "alt-bmc")"
249  if [ -n "${altNum}" ]; then
250    altRwfs=$(ubinfo -a -d "${altNum}" | grep -w "rwfs") || true
251    if [ -n "${altRwfs}" ]; then
252      altVarMount="/media/alt/var"
253      mkdir -p "${altVarMount}"
254      if mount ubi"${altNum}":rwfs "${altVarMount}" -t ubifs -o defaults; then
255        mkdir -p "${altVarMount}"/persist/etc
256      fi
257    fi
258  fi
259}
260
261remount_ubi() {
262  bmcmtd="$(findmtd "bmc")"
263  altbmcmtd="$(findmtd "alt-bmc")"
264  mtds="${bmcmtd: -1}","${altbmcmtd: -1}"
265
266  rootubi="$(findrootubi)"
267  rootname="$(findname "${rootubi}")"
268
269  IFS=',' read -r -a arrayMtds <<< "$mtds"
270  for mtd in "${arrayMtds[@]}"; do
271    # Get information on all ubi volumes
272    ubinfo=$(ubinfo -d "${mtd}")
273    presentVolumes=${ubinfo##*:}
274    IFS=', ' read -r -a array <<< "$presentVolumes"
275    for element in "${array[@]}"; do
276      elementProperties=$(ubinfo -d "$mtd" -n "$element")
277      # Get ubi volume name by getting rid of additional properties
278      name=${elementProperties#*Name:}
279      name="${name%Character*}"
280      name="$(echo -e "${name}" | tr -d '[:space:]')"
281
282      if [[ ${name} == rofs-* ]]; then
283        if [[ "${name}" == "${rootname}" ]]; then
284          mountdir="/media/${name}-functional"
285        else
286          mountdir="/media/${name}"
287        fi
288
289        if [ ! -d "${mountdir}" ]; then
290          mkdir -p "${mountdir}"
291          # U-Boot will create the ubiblock for the running version, but not
292          # for the version on the other chip
293          if [ ! -e "/dev/ubiblock${mtd}_${element}" ]; then
294            ubiblock --create "/dev/ubi${mtd}_${element}"
295          fi
296          mount -t squashfs -o ro "/dev/ubiblock${mtd}_${element}" "${mountdir}"
297        fi
298      fi
299    done
300  done
301
302  set_wdt2bite
303}
304
305mount_static_alt() {
306  typ=$1
307  altFs=$2
308  mountName=$3
309  altNum="$(findmtdnum "${altFs}")"
310  if [ -n "${altNum}" ]; then
311    altFsMount="/run/media/${mountName}"
312    mkdir -p "${altFsMount}"
313    altFsBlock="/dev/mtdblock${altNum}"
314    mount -t "${typ}" "${altFsBlock}" "${altFsMount}"
315  fi
316}
317
318umount_static_alt() {
319  altFs=$1
320  altFsMount="/run/media/${altFs}"
321  umount "${altFsMount}"
322}
323
324# Read the current env variable and set it on the alternate boot env
325copy_env_var_to_alt() {
326  varName=$1
327  value="$(fw_printenv -n "${varName}")"
328  fw_setenv -c /etc/alt_fw_env.config "${varName}" "${value}"
329}
330
331# When the alternate bmc chip boots, u-boot thinks its the primary mtdX.
332# Therefore need to swap the chip numbers when copying the ubiblock and root to
333# alternate bmc u-boot environment.
334copy_ubiblock_to_alt() {
335  value="$(fw_printenv -n ubiblock)"
336  bmcNum="$(findmtdnum "bmc")"
337  altNum="$(findmtdnum "alt-bmc")"
338  replaceAlt="${value/${altNum},/${bmcNum},}"
339
340  if [[ "${value}" == "${replaceAlt}" ]]; then
341    replaceBmc="${value/${bmcNum},/${altNum},}"
342    value=${replaceBmc}
343  else
344    value=${replaceAlt}
345  fi
346
347  fw_setenv -c /etc/alt_fw_env.config ubiblock "${value}"
348}
349
350copy_root_to_alt() {
351  value="$(fw_printenv -n root)"
352  bmcNum="$(findmtdnum "bmc")"
353  altNum="$(findmtdnum "alt-bmc")"
354  replaceAlt="${value/${altNum}_/${bmcNum}_}"
355
356  if [[ "${value}" == "${replaceAlt}" ]]; then
357    replaceBmc="${value/${bmcNum}_/${altNum}_}"
358    value=${replaceBmc}
359  else
360    value=${replaceAlt}
361  fi
362
363  fw_setenv -c /etc/alt_fw_env.config root "${value}"
364}
365
366ubi_setenv() {
367    # The U-Boot environment maintains two banks of environment variables.
368    # The banks need to be consistent with each other to ensure that these
369    # variables can reliably be read from file. In order to guarantee that the
370    # banks are both correct, we need to run fw_setenv twice.
371    variable=$1
372    if [[ "$variable" == *"="* ]]; then
373        varName="${variable%=*}"
374        value="${variable##*=}"
375        # Write only if var is not set already to the requested value
376        currentValue="$(fw_printenv -n "${varName}" 2>/dev/null)" || true
377        if [[ "${currentValue}" != "${value}" ]]; then
378          fw_setenv "$varName" "$value"
379          fw_setenv "$varName" "$value"
380        fi
381    else
382        fw_setenv "$variable"
383        fw_setenv "$variable"
384    fi
385}
386
387mtd_write() {
388  flashmtd="$(findmtd "${reqmtd}")"
389  img="/tmp/images/${version}/${imgfile}"
390  flashcp -v "${img}" /dev/"${flashmtd}"
391}
392
393backup_env_vars() {
394  copy_env_var_to_alt kernelname
395  copy_ubiblock_to_alt
396  copy_root_to_alt
397}
398
399update_env_vars() {
400  vol="$(findubi rofs-"${flashid}")"
401  if [ -z "${vol}" ]; then
402    return 1
403  fi
404  ubidevid="${vol#ubi}"
405  block="/dev/ubiblock${ubidevid}"
406  if [ ! -e "${block}" ]; then
407    return 1
408  fi
409  ubi_setenv "kernelname=kernel-${flashid}"
410  ubi_setenv "ubiblock=${ubidevid//_/,}"
411  ubi_setenv "root=${block}"
412}
413
414#TODO: Replace the implementation with systemd-inhibitors lock
415#      once systemd/systemd#949 is resolved
416rebootguardenable() {
417  dir="/run/systemd/system/"
418  file="reboot-guard.conf"
419  units=("reboot" "poweroff" "halt")
420
421  for unit in "${units[@]}"; do
422    mkdir -p ${dir}"${unit}".target.d
423    echo -e "[Unit]\nRefuseManualStart=yes" >> ${dir}"${unit}".target.d/${file}
424  done
425}
426
427#TODO: Replace the implementation with systemd-inhibitors lock
428#      once systemd/systemd#949 is resolved
429rebootguarddisable() {
430  dir="/run/systemd/system/"
431  file="reboot-guard.conf"
432  units=("reboot" "poweroff" "halt")
433
434  for unit in "${units[@]}"; do
435    rm -rf ${dir}"${unit}".target.d/${file}
436  done
437}
438
439# Create a copy in the alt mtd
440create_vol_in_alt() {
441  alt="alt-bmc"
442  altmtd="$(findmtd "${alt}")"
443  if [ -n "${altmtd}" ]; then
444    reqmtd="${alt}"
445    reqmtd2="${alt}"
446    ubi_ro
447    ubi_updatevol
448  fi
449}
450
451# Copy contents of one MTD device to another
452mtd_copy() {
453  in=$1
454  out=$2
455
456  # Must erase MTD first to prevent corruption
457  flash_eraseall "${out}"
458  dd if="${in}" of="${out}"
459}
460
461mirroruboot() {
462  bmc="$(findmtd "u-boot")"
463  bmcdev="/dev/${bmc}"
464  alt="$(findmtd "alt-u-boot")"
465  altdev="/dev/${alt}"
466
467  checksum_bmc="$(md5sum "${bmcdev}")"
468  checksum_bmc="${checksum_bmc% *}"
469  checksum_alt="$(md5sum "${altdev}")"
470  checksum_alt="${checksum_alt% *}"
471
472  if [[ "${checksum_bmc}" != "${checksum_alt}" ]]; then
473    bmcenv="$(findmtd "u-boot-env")"
474    bmcenvdev="/dev/${bmcenv}"
475    altenv="$(findmtd "alt-u-boot-env")"
476    altenvdev="/dev/${altenv}"
477
478    echo "Mirroring U-boot to alt chip"
479    mtd_copy "${bmcdev}" "${altdev}"
480    mtd_copy "${bmcenvdev}" "${altenvdev}"
481
482    copy_ubiblock_to_alt
483    copy_root_to_alt
484  fi
485}
486
487# Compare the device where u-boot resides with an image file. Specify the full
488# path to the device and image file to use for the compare. Print a value of
489# "0" if identical, "1" otherwise.
490cmp_uboot() {
491  device="$1"
492  image="$2"
493
494  # Since the image file can be smaller than the device, copy the device to a
495  # tmp file and write the image file on top, then compare the sum of each.
496  # Use cat / redirection since busybox does not have the conv=notrunc option.
497  tmpFile="$(mktemp /tmp/ubootdev.XXXXXX)"
498  dd if="${device}" of="${tmpFile}"
499  devSum="$(sha256sum "${tmpFile}")"
500  cat < "${image}" 1<> "${tmpFile}"
501  imgSum="$(sha256sum "${tmpFile}")"
502  rm -f "${tmpFile}"
503
504  if [ "${imgSum}" == "${devSum}" ]; then
505    echo "0";
506  else
507    echo "1";
508  fi
509}
510
511# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b.
512# Return the label (a or b) for the running partition.
513mmc_get_primary_label() {
514  # Get root device /dev/mmcblkpX
515  rootmatch=" on / "
516  root="$(mount | grep "${rootmatch}")"
517  root="${root%${rootmatch}*}"
518
519  # Find the device label
520  if [[ $(readlink -f /dev/disk/by-partlabel/rofs-a) == "${root}" ]]; then
521    echo "a"
522  elif [[ $(readlink -f /dev/disk/by-partlabel/rofs-b) == "${root}" ]]; then
523    echo "b"
524  else
525    echo ""
526  fi
527}
528
529# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b.
530# Return the label (a or b) for the non-running partition.
531mmc_get_secondary_label() {
532  root="$(mmc_get_primary_label)"
533  if [[ "${root}" == "a" ]]; then
534    echo "b"
535  elif [[ "${root}" == "b" ]]; then
536    echo "a"
537  else
538    echo ""
539  fi
540}
541
542mmc_mount() {
543  primaryId="$(mmc_get_primary_label)"
544  secondaryId="$(mmc_get_secondary_label)"
545
546  primaryDir="${mediaDir}/rofs-${primaryId}-functional"
547  secondaryDir="${mediaDir}/rofs-${secondaryId}"
548
549  mkdir -p "${primaryDir}"
550  mkdir -p "${secondaryDir}"
551
552  mount PARTLABEL=rofs-"${primaryId}" "${primaryDir}" -t ext4 -o ro || rmdir "${primaryDir}"
553  mount PARTLABEL=rofs-"${secondaryId}" "${secondaryDir}" -t ext4 -o ro || rmdir "${secondaryDir}"
554}
555
556mmc_update() {
557  # Update u-boot if needed
558  bootPartition="mmcblk0boot0"
559  devUBoot="/dev/${bootPartition}"
560  imgUBoot="${imgpath}/${version}/image-u-boot"
561  if [ "$(cmp_uboot "${devUBoot}" "${imgUBoot}")" != "0" ]; then
562    echo 0 > "/sys/block/${bootPartition}/force_ro"
563    dd if="${imgUBoot}" of="${devUBoot}"
564    echo 1 > "/sys/block/${bootPartition}/force_ro"
565  fi
566
567  # Update the secondary (non-running) boot and rofs partitions.
568  label="$(mmc_get_secondary_label)"
569
570  # Update the boot and rootfs partitions, restore their labels after the update
571  # by getting the partition number mmcblk0pX from their label.
572  zstd -d -c "${imgpath}"/"${version}"/image-kernel | dd of="/dev/disk/by-partlabel/boot-${label}"
573  number="$(readlink -f /dev/disk/by-partlabel/boot-"${label}")"
574  number="${number##*mmcblk0p}"
575  sgdisk --change-name="${number}":boot-"${label}" /dev/mmcblk0 1>/dev/null
576
577  zstd -d -c "${imgpath}"/"${version}"/image-rofs | dd of="/dev/disk/by-partlabel/rofs-${label}"
578  number="$(readlink -f /dev/disk/by-partlabel/rofs-"${label}")"
579  number="${number##*mmcblk0p}"
580  sgdisk --change-name="${number}":rofs-"${label}" /dev/mmcblk0 1>/dev/null
581
582  # Run this after sgdisk for labels to take effect.
583  partprobe
584
585  # Update hostfw
586  if [ -f "${imgpath}"/"${version}"/image-hostfw ]; then
587    # Remove patches
588    patchdir="/usr/local/share/hostfw/alternate"
589    if [ -d "${patchdir}" ]; then
590      rm -rf "${patchdir:?}"/*
591    fi
592    hostfwdir=$(grep "hostfw " /proc/mounts | cut -d " " -f 2)
593    cp "${imgpath}"/"${version}"/image-hostfw "${hostfwdir}"/hostfw-"${label}"
594    mkdir -p "${hostfwdir}"/alternate
595    mount "${hostfwdir}"/hostfw-"${label}" "${hostfwdir}"/alternate -o ro
596  fi
597
598  set_flashid "${label}"
599}
600
601mmc_remove() {
602  # Render the filesystem unbootable by wiping out the first 1MB, this
603  # invalidates the filesystem header.
604  # Check if the requested id is the one the BMC is running from since dd
605  # can still write and corrupt the running partition.
606  primaryid="$(mmc_get_primary_label)"
607  if [[ "${flashid}" == "${primaryid}" ]]; then
608    return 1
609  fi
610  dd if=/dev/zero of=/dev/disk/by-partlabel/boot-"${flashid}" count=2048
611  dd if=/dev/zero of=/dev/disk/by-partlabel/rofs-"${flashid}" count=2048
612
613  hostfw_alt="hostfw/alternate"
614  if grep -q "${hostfw_alt}" /proc/mounts; then
615    hostfw_alt=$(grep "${hostfw_alt}" /proc/mounts | cut -d " " -f 2)
616    umount "${hostfw_alt}"
617  fi
618  hostfw_base="hostfw "
619  if grep -q "${hostfw_base}" /proc/mounts; then
620    hostfw_base=$(grep "${hostfw_base}" /proc/mounts | cut -d " " -f 2)
621    rm -f "${hostfw_base}/hostfw-${flashid}"
622  fi
623}
624
625# Set the requested version as primary for the BMC to boot from upon reboot.
626mmc_setprimary() {
627  # Point root to the flashid of the requested BMC rootfs.
628  fw_setenv bootside "${flashid}"
629}
630
631case "$1" in
632  mtduboot)
633    reqmtd="$2"
634    version="$3"
635    imgfile="image-u-boot"
636    mtd_write
637    ;;
638  ubirw)
639    reqmtd="$2"
640    name="$3"
641    imgsize="$4"
642    ubi_rw
643    ;;
644  ubiro)
645    reqmtd="$(echo "$2" | cut -d "+" -f 1)"
646    reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
647    name="$3"
648    version="$4"
649    imgfile="image-rofs"
650    ubi_ro
651    ubi_updatevol
652    ubi_block
653    ;;
654  ubikernel)
655    reqmtd="$(echo "$2" | cut -d "+" -f 1)"
656    reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
657    name="$3"
658    version="$4"
659    imgfile="image-kernel"
660    ubi_ro
661    ubi_updatevol
662    create_vol_in_alt
663    ;;
664  ubiremove)
665    name="$2"
666    ubi_remove "${name}"
667    ;;
668  ubicleanup)
669    ubi_cleanup
670    ;;
671  ubisetenv)
672    ubi_setenv "$2"
673    ;;
674  ubiremount)
675    remount_ubi
676    mount_ubi_alt_rwfs
677    ;;
678  createenvbackup)
679    backup_env_vars
680    ;;
681  updateubootvars)
682    flashid="$2"
683    update_env_vars
684    ;;
685  rebootguardenable)
686    rebootguardenable
687    ;;
688  rebootguarddisable)
689    rebootguarddisable
690    ;;
691  mirroruboot)
692    mirroruboot
693    ;;
694  mmc)
695    version="$2"
696    imgpath="$3"
697    mmc_update
698    ;;
699  mmc-mount)
700    mediaDir="$2"
701    mmc_mount
702    ;;
703  mmc-remove)
704    flashid="$2"
705    mmc_remove
706    ;;
707  mmc-setprimary)
708    flashid="$2"
709    mmc_setprimary
710    ;;
711  static-altfs)
712    mount_static_alt "$2" "$3" "$4"
713    ;;
714  umount-static-altfs)
715    umount_static_alt "$2"
716    ;;
717  *)
718    echo "Invalid argument"
719    exit 1
720    ;;
721esac
722