1#!/bin/bash
2set -eo pipefail
3
4# Get the root mtd device number (mtdX) from "/dev/ubiblockX_Y on /"
5function findrootmtd() {
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
17function findrootubi() {
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)
26function findmtd() {
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)
34function findmtdnum() {
35    m="$(findmtd "$1")"
36    m="${m##mtd}"
37    echo "${m}"
38}
39
40# Get the ubi device number (ubiX_Y)
41function findubi() {
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
49function findubi_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
57function findubiname_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
65function findname() {
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
72function set_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
80function set_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
91function ubi_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
125function ubi_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
144function ubi_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
187function ubi_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
196function ubi_updatevol() {
197    vol="$(findubi "${name}")"
198    ubidevid="${vol#ubi}"
199    img="/tmp/images/${version}/${imgfile}"
200    ubiupdatevol "/dev/ubi${ubidevid}" "${img}"
201}
202
203function ubi_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
225function ubi_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
247function mount_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
261function remount_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
305function mount_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
318function umount_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
325function copy_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.
334function copy_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
350function copy_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
366function ubi_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
387function mtd_write() {
388    flashmtd="$(findmtd "${reqmtd}")"
389    img="/tmp/images/${version}/${imgfile}"
390    flashcp -v "${img}" /dev/"${flashmtd}"
391}
392
393function backup_env_vars() {
394    copy_env_var_to_alt kernelname
395    copy_ubiblock_to_alt
396    copy_root_to_alt
397}
398
399function update_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
416function rebootguardenable() {
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
429function rebootguarddisable() {
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
440function create_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
452function mtd_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
461function mirroruboot() {
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.
490function cmp_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.
513function mmc_get_primary_label() {
514    # Get root device /dev/mmcblkpX
515    rootmatch=" on / "
516    root="$(mount | grep "${rootmatch}")"
517    # shellcheck disable=SC2295
518    root="${root%${rootmatch}*}"
519
520    # Find the device label
521    if [[ $(readlink -f /dev/disk/by-partlabel/rofs-a) == "${root}" ]]; then
522        echo "a"
523    elif [[ $(readlink -f /dev/disk/by-partlabel/rofs-b) == "${root}" ]]; then
524        echo "b"
525    else
526        echo ""
527    fi
528}
529
530# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b.
531# Return the label (a or b) for the non-running partition.
532function mmc_get_secondary_label() {
533    root="$(mmc_get_primary_label)"
534    if [[ "${root}" == "a" ]]; then
535        echo "b"
536    elif [[ "${root}" == "b" ]]; then
537        echo "a"
538    else
539        echo ""
540    fi
541}
542
543function mmc_mount() {
544    primaryId="$(mmc_get_primary_label)"
545    secondaryId="$(mmc_get_secondary_label)"
546
547    primaryDir="${mediaDir}/rofs-${primaryId}-functional"
548    secondaryDir="${mediaDir}/rofs-${secondaryId}"
549
550    # Check the alternate version, remove it if it's corrupted. This can occur
551    # when the BMC is rebooted in the middle of a code update for example.
552    if ! fsck.ext4 -p "/dev/disk/by-partlabel/rofs-${secondaryId}"; then
553        flashid="${secondaryId}"
554        mmc_remove
555    fi
556
557    mkdir -p "${primaryDir}"
558    mkdir -p "${secondaryDir}"
559
560    mount PARTLABEL=rofs-"${primaryId}" "${primaryDir}" -t ext4 -o ro || rmdir "${primaryDir}"
561    mount PARTLABEL=rofs-"${secondaryId}" "${secondaryDir}" -t ext4 -o ro || rmdir "${secondaryDir}"
562}
563
564function mmc_update() {
565    # Update u-boot if needed
566    bootPartition="mmcblk0boot0"
567    devUBoot="/dev/${bootPartition}"
568    imgUBoot="${imgpath}/${version}/image-u-boot"
569    if [ "$(cmp_uboot "${devUBoot}" "${imgUBoot}")" != "0" ]; then
570        echo 0 > "/sys/block/${bootPartition}/force_ro"
571        dd if="${imgUBoot}" of="${devUBoot}"
572        echo 1 > "/sys/block/${bootPartition}/force_ro"
573    fi
574
575    # Update the secondary (non-running) boot and rofs partitions.
576    label="$(mmc_get_secondary_label)"
577
578    # Update the boot and rootfs partitions, restore their labels after the update
579    # by getting the partition number mmcblk0pX from their label.
580    zstd -d -c "${imgpath}"/"${version}"/image-kernel | dd of="/dev/disk/by-partlabel/boot-${label}"
581    number="$(readlink -f /dev/disk/by-partlabel/boot-"${label}")"
582    number="${number##*mmcblk0p}"
583    sgdisk --change-name="${number}":boot-"${label}" /dev/mmcblk0 1>/dev/null
584
585    zstd -d -c "${imgpath}"/"${version}"/image-rofs | dd of="/dev/disk/by-partlabel/rofs-${label}"
586    number="$(readlink -f /dev/disk/by-partlabel/rofs-"${label}")"
587    number="${number##*mmcblk0p}"
588    sgdisk --change-name="${number}":rofs-"${label}" /dev/mmcblk0 1>/dev/null
589
590    # Run this after sgdisk for labels to take effect.
591    partprobe
592
593    # Update hostfw. The remove function doesn't touch the hostfw image, so
594    # need to unmount and delete it prior to updating it.
595    if [ -f "${imgpath}"/"${version}"/image-hostfw ]; then
596        # Remove patches
597        hostfw_alt="hostfw/alternate"
598        patchdir="/usr/local/share/${hostfw_alt}"
599        if [ -d "${patchdir}" ]; then
600            rm -rf "${patchdir:?}"/*
601        fi
602        if grep -q "${hostfw_alt}" /proc/mounts; then
603            hostfw_alt=$(grep "${hostfw_alt}" /proc/mounts | cut -d " " -f 2)
604            umount "${hostfw_alt}"
605        fi
606        hostfwdir=$(grep "hostfw " /proc/mounts | cut -d " " -f 2)
607        rm -f "${hostfwdir}/hostfw-${flashid}"
608        cp "${imgpath}"/"${version}"/image-hostfw "${hostfwdir}"/hostfw-"${label}"
609        mkdir -p "${hostfwdir}"/alternate
610        mount "${hostfwdir}"/hostfw-"${label}" "${hostfwdir}"/alternate -o ro
611    fi
612
613    set_flashid "${label}"
614}
615
616function mmc_remove() {
617    # Render the filesystem unbootable by wiping out the first 1MB, this
618    # invalidates the filesystem header.
619    # Check if the requested id is the one the BMC is running from since dd
620    # can still write and corrupt the running partition.
621    primaryid="$(mmc_get_primary_label)"
622    if [[ "${flashid}" == "${primaryid}" ]]; then
623        return 1
624    fi
625    dd if=/dev/zero of=/dev/disk/by-partlabel/boot-"${flashid}" count=2048
626    dd if=/dev/zero of=/dev/disk/by-partlabel/rofs-"${flashid}" count=2048
627}
628
629# Set the requested version as primary for the BMC to boot from upon reboot.
630function mmc_setprimary() {
631    # Point root to the flashid of the requested BMC rootfs.
632    fw_setenv bootside "${flashid}"
633}
634
635function mmc_mirroruboot() {
636    # Get current boot device; 0-primary_bootdev device; 1 - alt_bootdev
637    bootdev=$(cat /sys/kernel/debug/aspeed/sbc/abr_image)
638    if [[ "${bootdev}" == "0" ]]; then
639        bootPartition="mmcblk0boot0"
640        alt_bootPartition="mmcblk0boot1"
641    else
642        bootPartition="mmcblk0boot1"
643        alt_bootPartition="mmcblk0boot0"
644    fi
645
646    devUBoot="/dev/${bootPartition}"
647    alt_devUBoot="/dev/${alt_bootPartition}"
648
649    checksum_UBoot="$(md5sum "${devUBoot}")"
650    checksum_UBoot="${checksum_UBoot% *}"
651    checksum_alt_UBoot="$(md5sum "${alt_devUBoot}")"
652    checksum_alt_UBoot="${checksum_alt% *}"
653
654    if [[ "${checksum_UBoot}" != "${checksum_alt_UBoot}" ]]; then
655        echo "Mirroring U-boot to alt chip"
656        echo 0 > "/sys/block/${alt_bootPartition}/force_ro"
657        dd if="${devUBoot}" of="${alt_devUBoot}"
658        echo 1 > "/sys/block/${alt_bootPartition}/force_ro"
659    fi
660}
661
662case "$1" in
663    mtduboot)
664        reqmtd="$2"
665        version="$3"
666        imgfile="image-u-boot"
667        mtd_write
668        ;;
669    ubirw)
670        reqmtd="$2"
671        name="$3"
672        imgsize="$4"
673        ubi_rw
674        ;;
675    ubiro)
676        reqmtd="$(echo "$2" | cut -d "+" -f 1)"
677        reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
678        name="$3"
679        version="$4"
680        imgfile="image-rofs"
681        ubi_ro
682        ubi_updatevol
683        ubi_block
684        ;;
685    ubikernel)
686        reqmtd="$(echo "$2" | cut -d "+" -f 1)"
687        reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
688        name="$3"
689        version="$4"
690        imgfile="image-kernel"
691        ubi_ro
692        ubi_updatevol
693        create_vol_in_alt
694        ;;
695    ubiremove)
696        name="$2"
697        ubi_remove "${name}"
698        ;;
699    ubicleanup)
700        ubi_cleanup
701        ;;
702    ubisetenv)
703        ubi_setenv "$2"
704        ;;
705    ubiremount)
706        remount_ubi
707        mount_ubi_alt_rwfs
708        ;;
709    createenvbackup)
710        backup_env_vars
711        ;;
712    updateubootvars)
713        flashid="$2"
714        update_env_vars
715        ;;
716    rebootguardenable)
717        rebootguardenable
718        ;;
719    rebootguarddisable)
720        rebootguarddisable
721        ;;
722    mirroruboot)
723        mirroruboot
724        ;;
725    mmc)
726        version="$2"
727        imgpath="$3"
728        mmc_update
729        ;;
730    mmc-mount)
731        mediaDir="$2"
732        mmc_mount
733        ;;
734    mmc-remove)
735        flashid="$2"
736        mmc_remove
737        ;;
738    mmc-setprimary)
739        flashid="$2"
740        mmc_setprimary
741        ;;
742    mmc-mirroruboot)
743        mmc_mirroruboot
744        ;;
745    static-altfs)
746        mount_static_alt "$2" "$3" "$4"
747        ;;
748    umount-static-altfs)
749        umount_static_alt "$2"
750        ;;
751    *)
752        echo "Invalid argument"
753        exit 1
754        ;;
755esac
756