blob: b76ad62c0ffd93f3c4fa2cbc03a0eaf006829434 [file] [log] [blame]
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -05001#!/bin/bash
2set -eo pipefail
3
4# Get the root mtd device number (mtdX) from "/dev/ubiblockX_Y on /"
Patrick Williams780c9302022-12-08 06:34:04 -06005function 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}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050015}
16
Patrick Williams780c9302022-12-08 06:34:04 -060017function findrootubi() {
18 rootmatch=" on / "
19 m="$(mount | grep "${rootmatch}")"
20 m="${m##*ubiblock}"
21 m="${m% on*}"
22 echo "ubi${m}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050023}
24
25# Get the mtd device number (mtdX)
Patrick Williams780c9302022-12-08 06:34:04 -060026function findmtd() {
27 m="$(grep -xl "$1" /sys/class/mtd/*/name)"
28 m="${m%/name}"
29 m="${m##*/}"
30 echo "${m}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050031}
32
33# Get the mtd device number only (return X of mtdX)
Patrick Williams780c9302022-12-08 06:34:04 -060034function findmtdnum() {
35 m="$(findmtd "$1")"
36 m="${m##mtd}"
37 echo "${m}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050038}
39
40# Get the ubi device number (ubiX_Y)
Patrick Williams780c9302022-12-08 06:34:04 -060041function findubi() {
42 u="$(grep -xl "$1" /sys/class/ubi/ubi?/subsystem/ubi*/name)"
43 u="${u%/name}"
44 u="${u##*/}"
45 echo "${u}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050046}
47
48# Get the ubi device number (ubiX_Y) on a specific mtd
Patrick Williams780c9302022-12-08 06:34:04 -060049function 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}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050054}
55
56# Get all ubi device names on a specific mtd that match requested string
Patrick Williams780c9302022-12-08 06:34:04 -060057function 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}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050062}
63
64# Get the name from the requested ubiX_Y volume
Patrick Williams780c9302022-12-08 06:34:04 -060065function findname() {
66 n="$(cat /sys/class/ubi/"$1"/name)"
67 echo "${n}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050068}
69
Adriana Kobylaka84f06d2022-01-18 15:41:57 +000070# Set the version path property to the flash location where the image was
71# successfully flashed
Patrick Williams780c9302022-12-08 06:34:04 -060072function 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"
Adriana Kobylaka84f06d2022-01-18 15:41:57 +000077}
78
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050079# Set the u-boot envs that perform a side switch on failure to boot
Patrick Williams780c9302022-12-08 06:34:04 -060080function 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 \
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050085\${loadaddr} \${kernelname}; bootm \${loadaddr} || run bootalt"
Patrick Williams780c9302022-12-08 06:34:04 -060086 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050087}
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
Patrick Williams780c9302022-12-08 06:34:04 -060091function ubi_remove_volumes()
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050092{
Patrick Williams780c9302022-12-08 06:34:04 -060093 rootubi="$(findrootubi)"
94 rootname="$(findname "${rootubi}")"
95 rootversion="${rootname##*-}"
96 rootkernel="kernel-${rootversion}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050097
Patrick Williams780c9302022-12-08 06:34:04 -060098 # 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-- ))
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500122 done
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500123}
124
Patrick Williams780c9302022-12-08 06:34:04 -0600125function ubi_rw() {
126 rwmtd="$(findmtd "${reqmtd}")"
127 rw="${rwmtd#mtd}"
128 ubidev="/dev/ubi${rw}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500129
Patrick Williams780c9302022-12-08 06:34:04 -0600130 # 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500136 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500137
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500138 vol="$(findubi "${name}")"
Patrick Williams780c9302022-12-08 06:34:04 -0600139 if [ -z "${vol}" ]; then
140 ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}"
141 fi
142}
Adriana Kobylaka84f06d2022-01-18 15:41:57 +0000143
Patrick Williams780c9302022-12-08 06:34:04 -0600144function 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}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500184}
185
186# Squashfs images need a ubi block
Patrick Williams780c9302022-12-08 06:34:04 -0600187function 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500194}
195
Patrick Williams780c9302022-12-08 06:34:04 -0600196function ubi_updatevol() {
197 vol="$(findubi "${name}")"
198 ubidevid="${vol#ubi}"
199 img="/tmp/images/${version}/${imgfile}"
200 ubiupdatevol "/dev/ubi${ubidevid}" "${img}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500201}
202
Patrick Williams780c9302022-12-08 06:34:04 -0600203function ubi_remove() {
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500204 rmname="$1"
205 rmmtd="$2"
Isaac Kurthc53fcca2022-02-02 15:24:33 -0600206 if [ -n "${rmmtd}" ]; then
Patrick Williams780c9302022-12-08 06:34:04 -0600207 vol="$(findubi_onmtd "${rmname}" "${rmmtd}")"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500208 else
Patrick Williams780c9302022-12-08 06:34:04 -0600209 vol="$(findubi "${rmname}")"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500210 fi
211
Isaac Kurthc53fcca2022-02-02 15:24:33 -0600212 if [ -n "$vol" ]; then
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500213 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
Patrick Williams780c9302022-12-08 06:34:04 -0600225function ubi_cleanup() {
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500226 # 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 | \
Patrick Williams780c9302022-12-08 06:34:04 -0600229 grep /xyz/openbmc_project/software/ | tail -c 9)
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500230
231 if [[ -z "$activeVersion" ]]; then
232 vols=$(ubinfo -a | grep "rofs-" | cut -c 14-)
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500233 else
Adriana Kobylak25773a72022-01-21 15:24:48 +0000234 flashid=$(busctl get-property xyz.openbmc_project.Software.BMC.Updater \
Patrick Williams780c9302022-12-08 06:34:04 -0600235 "/xyz/openbmc_project/software/${activeVersion}" \
Adriana Kobylak25773a72022-01-21 15:24:48 +0000236 xyz.openbmc_project.Common.FilePath Path | awk '{print $NF;}' | tr -d '"')
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500237 vols=$(ubinfo -a | grep "rofs-" | \
Patrick Williams780c9302022-12-08 06:34:04 -0600238 grep -v "$flashid" | cut -c 14-) || true
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500239 fi
240
Isaac Kurthc53fcca2022-02-02 15:24:33 -0600241 mapfile -t array <<< "${vols}"
242 for (( index=0; index<${#array[@]}; index++ )); do
Patrick Williams780c9302022-12-08 06:34:04 -0600243 ubi_remove "${array[index]}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500244 done
245}
246
Patrick Williams780c9302022-12-08 06:34:04 -0600247function 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500258 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500259}
260
Patrick Williams780c9302022-12-08 06:34:04 -0600261function remount_ubi() {
262 bmcmtd="$(findmtd "bmc")"
263 altbmcmtd="$(findmtd "alt-bmc")"
264 mtds="${bmcmtd: -1}","${altbmcmtd: -1}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500265
Patrick Williams780c9302022-12-08 06:34:04 -0600266 rootubi="$(findrootubi)"
267 rootname="$(findname "${rootubi}")"
Adriana Kobylak1e81f232022-01-18 22:28:47 +0000268
Patrick Williams780c9302022-12-08 06:34:04 -0600269 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:]')"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500281
Patrick Williams780c9302022-12-08 06:34:04 -0600282 if [[ ${name} == rofs-* ]]; then
283 if [[ "${name}" == "${rootname}" ]]; then
284 mountdir="/media/${name}-functional"
285 else
286 mountdir="/media/${name}"
287 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500288
Patrick Williams780c9302022-12-08 06:34:04 -0600289 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500300 done
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500301
Patrick Williams780c9302022-12-08 06:34:04 -0600302 set_wdt2bite
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500303}
304
Patrick Williams780c9302022-12-08 06:34:04 -0600305function 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
Lei YU63769642021-12-10 16:15:04 +0800316}
317
Patrick Williams780c9302022-12-08 06:34:04 -0600318function umount_static_alt() {
319 altFs=$1
320 altFsMount="/run/media/${altFs}"
321 umount "${altFsMount}"
Lei YUb5171ac2021-12-16 18:36:27 +0800322}
323
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500324# Read the current env variable and set it on the alternate boot env
Patrick Williams780c9302022-12-08 06:34:04 -0600325function 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}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500329}
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.
Patrick Williams780c9302022-12-08 06:34:04 -0600334function copy_ubiblock_to_alt() {
335 value="$(fw_printenv -n ubiblock)"
336 bmcNum="$(findmtdnum "bmc")"
337 altNum="$(findmtdnum "alt-bmc")"
338 replaceAlt="${value/${altNum},/${bmcNum},}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500339
Patrick Williams780c9302022-12-08 06:34:04 -0600340 if [[ "${value}" == "${replaceAlt}" ]]; then
341 replaceBmc="${value/${bmcNum},/${altNum},}"
342 value=${replaceBmc}
343 else
344 value=${replaceAlt}
345 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500346
Patrick Williams780c9302022-12-08 06:34:04 -0600347 fw_setenv -c /etc/alt_fw_env.config ubiblock "${value}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500348}
349
Patrick Williams780c9302022-12-08 06:34:04 -0600350function copy_root_to_alt() {
351 value="$(fw_printenv -n root)"
352 bmcNum="$(findmtdnum "bmc")"
353 altNum="$(findmtdnum "alt-bmc")"
354 replaceAlt="${value/${altNum}_/${bmcNum}_}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500355
Patrick Williams780c9302022-12-08 06:34:04 -0600356 if [[ "${value}" == "${replaceAlt}" ]]; then
357 replaceBmc="${value/${bmcNum}_/${altNum}_}"
358 value=${replaceBmc}
359 else
360 value=${replaceAlt}
361 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500362
Patrick Williams780c9302022-12-08 06:34:04 -0600363 fw_setenv -c /etc/alt_fw_env.config root "${value}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500364}
365
Patrick Williams780c9302022-12-08 06:34:04 -0600366function ubi_setenv() {
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500367 # 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
Isaac Kurthc53fcca2022-02-02 15:24:33 -0600377 if [[ "${currentValue}" != "${value}" ]]; then
Patrick Williams780c9302022-12-08 06:34:04 -0600378 fw_setenv "$varName" "$value"
379 fw_setenv "$varName" "$value"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500380 fi
381 else
382 fw_setenv "$variable"
383 fw_setenv "$variable"
384 fi
385}
386
Patrick Williams780c9302022-12-08 06:34:04 -0600387function mtd_write() {
388 flashmtd="$(findmtd "${reqmtd}")"
389 img="/tmp/images/${version}/${imgfile}"
390 flashcp -v "${img}" /dev/"${flashmtd}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500391}
392
Patrick Williams780c9302022-12-08 06:34:04 -0600393function backup_env_vars() {
394 copy_env_var_to_alt kernelname
395 copy_ubiblock_to_alt
396 copy_root_to_alt
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500397}
398
Patrick Williams780c9302022-12-08 06:34:04 -0600399function 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}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500412}
413
414#TODO: Replace the implementation with systemd-inhibitors lock
415# once systemd/systemd#949 is resolved
Patrick Williams780c9302022-12-08 06:34:04 -0600416function rebootguardenable() {
417 dir="/run/systemd/system/"
418 file="reboot-guard.conf"
419 units=("reboot" "poweroff" "halt")
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500420
Patrick Williams780c9302022-12-08 06:34:04 -0600421 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500425}
426
427#TODO: Replace the implementation with systemd-inhibitors lock
428# once systemd/systemd#949 is resolved
Patrick Williams780c9302022-12-08 06:34:04 -0600429function rebootguarddisable() {
430 dir="/run/systemd/system/"
431 file="reboot-guard.conf"
432 units=("reboot" "poweroff" "halt")
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500433
Patrick Williams780c9302022-12-08 06:34:04 -0600434 for unit in "${units[@]}"; do
435 rm -rf ${dir}"${unit}".target.d/${file}
436 done
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500437}
438
439# Create a copy in the alt mtd
Patrick Williams780c9302022-12-08 06:34:04 -0600440function 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500449}
450
451# Copy contents of one MTD device to another
Patrick Williams780c9302022-12-08 06:34:04 -0600452function mtd_copy() {
453 in=$1
454 out=$2
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500455
Patrick Williams780c9302022-12-08 06:34:04 -0600456 # Must erase MTD first to prevent corruption
457 flash_eraseall "${out}"
458 dd if="${in}" of="${out}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500459}
460
Patrick Williams780c9302022-12-08 06:34:04 -0600461function mirroruboot() {
462 bmc="$(findmtd "u-boot")"
463 bmcdev="/dev/${bmc}"
464 alt="$(findmtd "alt-u-boot")"
465 altdev="/dev/${alt}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500466
Patrick Williams780c9302022-12-08 06:34:04 -0600467 checksum_bmc="$(md5sum "${bmcdev}")"
468 checksum_bmc="${checksum_bmc% *}"
469 checksum_alt="$(md5sum "${altdev}")"
470 checksum_alt="${checksum_alt% *}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500471
Patrick Williams780c9302022-12-08 06:34:04 -0600472 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}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500477
Patrick Williams780c9302022-12-08 06:34:04 -0600478 echo "Mirroring U-boot to alt chip"
479 mtd_copy "${bmcdev}" "${altdev}"
480 mtd_copy "${bmcenvdev}" "${altenvdev}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500481
Patrick Williams780c9302022-12-08 06:34:04 -0600482 copy_ubiblock_to_alt
483 copy_root_to_alt
484 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500485}
486
Adriana Kobylak62f38202020-09-29 13:04:25 -0500487# 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.
Patrick Williams780c9302022-12-08 06:34:04 -0600490function cmp_uboot() {
491 device="$1"
492 image="$2"
Adriana Kobylak62f38202020-09-29 13:04:25 -0500493
Patrick Williams780c9302022-12-08 06:34:04 -0600494 # 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}"
Adriana Kobylak62f38202020-09-29 13:04:25 -0500503
Patrick Williams780c9302022-12-08 06:34:04 -0600504 if [ "${imgSum}" == "${devSum}" ]; then
505 echo "0";
506 else
507 echo "1";
508 fi
Adriana Kobylak62f38202020-09-29 13:04:25 -0500509}
510
Adriana Kobylak70f5bc02020-05-13 14:08:14 -0500511# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b.
Adriana Kobylak34124352020-05-22 09:40:40 -0500512# Return the label (a or b) for the running partition.
Patrick Williams780c9302022-12-08 06:34:04 -0600513function 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}*}"
Adriana Kobylak5312d852020-07-18 09:49:34 -0500519
Patrick Williams780c9302022-12-08 06:34:04 -0600520 # 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
Adriana Kobylak34124352020-05-22 09:40:40 -0500528}
529
530# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b.
Adriana Kobylak70f5bc02020-05-13 14:08:14 -0500531# Return the label (a or b) for the non-running partition.
Patrick Williams780c9302022-12-08 06:34:04 -0600532function 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 ""
Adriana Kobylakd148b4f2020-08-27 10:18:49 -0500540 fi
Adriana Kobylak70f5bc02020-05-13 14:08:14 -0500541}
542
Patrick Williams780c9302022-12-08 06:34:04 -0600543function mmc_mount() {
544 primaryId="$(mmc_get_primary_label)"
545 secondaryId="$(mmc_get_secondary_label)"
Adriana Kobylak8c5209d2020-07-12 13:35:47 -0500546
Patrick Williams780c9302022-12-08 06:34:04 -0600547 primaryDir="${mediaDir}/rofs-${primaryId}-functional"
548 secondaryDir="${mediaDir}/rofs-${secondaryId}"
549
550 mkdir -p "${primaryDir}"
551 mkdir -p "${secondaryDir}"
552
553 mount PARTLABEL=rofs-"${primaryId}" "${primaryDir}" -t ext4 -o ro || rmdir "${primaryDir}"
554 mount PARTLABEL=rofs-"${secondaryId}" "${secondaryDir}" -t ext4 -o ro || rmdir "${secondaryDir}"
555}
556
557function mmc_update() {
558 # Update u-boot if needed
559 bootPartition="mmcblk0boot0"
560 devUBoot="/dev/${bootPartition}"
561 imgUBoot="${imgpath}/${version}/image-u-boot"
562 if [ "$(cmp_uboot "${devUBoot}" "${imgUBoot}")" != "0" ]; then
563 echo 0 > "/sys/block/${bootPartition}/force_ro"
564 dd if="${imgUBoot}" of="${devUBoot}"
565 echo 1 > "/sys/block/${bootPartition}/force_ro"
566 fi
567
568 # Update the secondary (non-running) boot and rofs partitions.
569 label="$(mmc_get_secondary_label)"
570
571 # Update the boot and rootfs partitions, restore their labels after the update
572 # by getting the partition number mmcblk0pX from their label.
573 zstd -d -c "${imgpath}"/"${version}"/image-kernel | dd of="/dev/disk/by-partlabel/boot-${label}"
574 number="$(readlink -f /dev/disk/by-partlabel/boot-"${label}")"
575 number="${number##*mmcblk0p}"
576 sgdisk --change-name="${number}":boot-"${label}" /dev/mmcblk0 1>/dev/null
577
578 zstd -d -c "${imgpath}"/"${version}"/image-rofs | dd of="/dev/disk/by-partlabel/rofs-${label}"
579 number="$(readlink -f /dev/disk/by-partlabel/rofs-"${label}")"
580 number="${number##*mmcblk0p}"
581 sgdisk --change-name="${number}":rofs-"${label}" /dev/mmcblk0 1>/dev/null
582
583 # Run this after sgdisk for labels to take effect.
584 partprobe
585
586 # Update hostfw
587 if [ -f "${imgpath}"/"${version}"/image-hostfw ]; then
588 # Remove patches
589 patchdir="/usr/local/share/hostfw/alternate"
590 if [ -d "${patchdir}" ]; then
591 rm -rf "${patchdir:?}"/*
592 fi
593 hostfwdir=$(grep "hostfw " /proc/mounts | cut -d " " -f 2)
594 cp "${imgpath}"/"${version}"/image-hostfw "${hostfwdir}"/hostfw-"${label}"
595 mkdir -p "${hostfwdir}"/alternate
596 mount "${hostfwdir}"/hostfw-"${label}" "${hostfwdir}"/alternate -o ro
597 fi
598
599 set_flashid "${label}"
600}
601
602function mmc_remove() {
603 # Render the filesystem unbootable by wiping out the first 1MB, this
604 # invalidates the filesystem header.
605 # Check if the requested id is the one the BMC is running from since dd
606 # can still write and corrupt the running partition.
607 primaryid="$(mmc_get_primary_label)"
608 if [[ "${flashid}" == "${primaryid}" ]]; then
609 return 1
610 fi
611 dd if=/dev/zero of=/dev/disk/by-partlabel/boot-"${flashid}" count=2048
612 dd if=/dev/zero of=/dev/disk/by-partlabel/rofs-"${flashid}" count=2048
613
614 hostfw_alt="hostfw/alternate"
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 hostfw_base="hostfw "
620 if grep -q "${hostfw_base}" /proc/mounts; then
621 hostfw_base=$(grep "${hostfw_base}" /proc/mounts | cut -d " " -f 2)
622 rm -f "${hostfw_base}/hostfw-${flashid}"
623 fi
Adriana Kobylak70f5bc02020-05-13 14:08:14 -0500624}
625
Adriana Kobylak34124352020-05-22 09:40:40 -0500626# Set the requested version as primary for the BMC to boot from upon reboot.
Patrick Williams780c9302022-12-08 06:34:04 -0600627function mmc_setprimary() {
628 # Point root to the flashid of the requested BMC rootfs.
629 fw_setenv bootside "${flashid}"
Adriana Kobylak34124352020-05-22 09:40:40 -0500630}
631
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500632case "$1" in
Patrick Williams780c9302022-12-08 06:34:04 -0600633 mtduboot)
634 reqmtd="$2"
635 version="$3"
636 imgfile="image-u-boot"
637 mtd_write
638 ;;
639 ubirw)
640 reqmtd="$2"
641 name="$3"
642 imgsize="$4"
643 ubi_rw
644 ;;
645 ubiro)
646 reqmtd="$(echo "$2" | cut -d "+" -f 1)"
647 reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
648 name="$3"
649 version="$4"
650 imgfile="image-rofs"
651 ubi_ro
652 ubi_updatevol
653 ubi_block
654 ;;
655 ubikernel)
656 reqmtd="$(echo "$2" | cut -d "+" -f 1)"
657 reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
658 name="$3"
659 version="$4"
660 imgfile="image-kernel"
661 ubi_ro
662 ubi_updatevol
663 create_vol_in_alt
664 ;;
665 ubiremove)
666 name="$2"
667 ubi_remove "${name}"
668 ;;
669 ubicleanup)
670 ubi_cleanup
671 ;;
672 ubisetenv)
673 ubi_setenv "$2"
674 ;;
675 ubiremount)
676 remount_ubi
677 mount_ubi_alt_rwfs
678 ;;
679 createenvbackup)
680 backup_env_vars
681 ;;
682 updateubootvars)
683 flashid="$2"
684 update_env_vars
685 ;;
686 rebootguardenable)
687 rebootguardenable
688 ;;
689 rebootguarddisable)
690 rebootguarddisable
691 ;;
692 mirroruboot)
693 mirroruboot
694 ;;
695 mmc)
696 version="$2"
697 imgpath="$3"
698 mmc_update
699 ;;
700 mmc-mount)
701 mediaDir="$2"
702 mmc_mount
703 ;;
704 mmc-remove)
705 flashid="$2"
706 mmc_remove
707 ;;
708 mmc-setprimary)
709 flashid="$2"
710 mmc_setprimary
711 ;;
712 static-altfs)
713 mount_static_alt "$2" "$3" "$4"
714 ;;
715 umount-static-altfs)
716 umount_static_alt "$2"
717 ;;
718 *)
719 echo "Invalid argument"
720 exit 1
721 ;;
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500722esac