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