blob: f9cc4e256e0f7b41b1d7391e10429b721a559ac6 [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() {
Adriana Kobylakdb3d9662024-12-06 14:55:44 -060073 busctl set-property xyz.openbmc_project.Software.Manager \
74 "/xyz/openbmc_project/software/${version}" \
75 xyz.openbmc_project.Common.FilePath \
76 Path s "$1" ||
Patrick Williams780c9302022-12-08 06:34:04 -060077 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"
Adriana Kobylaka84f06d2022-01-18 15:41:57 +000081}
82
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050083# Set the u-boot envs that perform a side switch on failure to boot
Patrick Williams780c9302022-12-08 06:34:04 -060084function 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 \
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050089\${loadaddr} \${kernelname}; bootm \${loadaddr} || run bootalt"
Patrick Williams780c9302022-12-08 06:34:04 -060090 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050091}
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
Patrick Williams780c9302022-12-08 06:34:04 -060095function ubi_remove_volumes()
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -050096{
Patrick Williams780c9302022-12-08 06:34:04 -060097 rootubi="$(findrootubi)"
98 rootname="$(findname "${rootubi}")"
99 rootversion="${rootname##*-}"
100 rootkernel="kernel-${rootversion}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500101
Patrick Williams780c9302022-12-08 06:34:04 -0600102 # 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-- ))
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500126 done
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500127}
128
Patrick Williams780c9302022-12-08 06:34:04 -0600129function ubi_rw() {
130 rwmtd="$(findmtd "${reqmtd}")"
131 rw="${rwmtd#mtd}"
132 ubidev="/dev/ubi${rw}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500133
Patrick Williams780c9302022-12-08 06:34:04 -0600134 # 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500140 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500141
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500142 vol="$(findubi "${name}")"
Patrick Williams780c9302022-12-08 06:34:04 -0600143 if [ -z "${vol}" ]; then
144 ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}"
145 fi
146}
Adriana Kobylaka84f06d2022-01-18 15:41:57 +0000147
Patrick Williams780c9302022-12-08 06:34:04 -0600148function 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}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500188}
189
190# Squashfs images need a ubi block
Patrick Williams780c9302022-12-08 06:34:04 -0600191function 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500198}
199
Patrick Williams780c9302022-12-08 06:34:04 -0600200function ubi_updatevol() {
201 vol="$(findubi "${name}")"
202 ubidevid="${vol#ubi}"
203 img="/tmp/images/${version}/${imgfile}"
204 ubiupdatevol "/dev/ubi${ubidevid}" "${img}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500205}
206
Patrick Williams780c9302022-12-08 06:34:04 -0600207function ubi_remove() {
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500208 rmname="$1"
209 rmmtd="$2"
Isaac Kurthc53fcca2022-02-02 15:24:33 -0600210 if [ -n "${rmmtd}" ]; then
Patrick Williams780c9302022-12-08 06:34:04 -0600211 vol="$(findubi_onmtd "${rmname}" "${rmmtd}")"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500212 else
Patrick Williams780c9302022-12-08 06:34:04 -0600213 vol="$(findubi "${rmname}")"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500214 fi
215
Isaac Kurthc53fcca2022-02-02 15:24:33 -0600216 if [ -n "$vol" ]; then
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500217 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
Patrick Williams780c9302022-12-08 06:34:04 -0600229function ubi_cleanup() {
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500230 # When ubi_cleanup is run, it expects one or no active version.
231 activeVersion=$(busctl --list --no-pager tree \
Adriana Kobylakdb3d9662024-12-06 14:55:44 -0600232 xyz.openbmc_project.Software.Manager | \
Patrick Williams780c9302022-12-08 06:34:04 -0600233 grep /xyz/openbmc_project/software/ | tail -c 9)
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500234
235 if [[ -z "$activeVersion" ]]; then
Adriana Kobylakdb3d9662024-12-06 14:55:44 -0600236 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500242 vols=$(ubinfo -a | grep "rofs-" | cut -c 14-)
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500243 else
Adriana Kobylakdb3d9662024-12-06 14:55:44 -0600244 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 '"') ||
Adriana Kobylak25773a72022-01-21 15:24:48 +0000247 flashid=$(busctl get-property xyz.openbmc_project.Software.BMC.Updater \
Patrick Williams780c9302022-12-08 06:34:04 -0600248 "/xyz/openbmc_project/software/${activeVersion}" \
Adriana Kobylak25773a72022-01-21 15:24:48 +0000249 xyz.openbmc_project.Common.FilePath Path | awk '{print $NF;}' | tr -d '"')
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500250 vols=$(ubinfo -a | grep "rofs-" | \
Patrick Williams780c9302022-12-08 06:34:04 -0600251 grep -v "$flashid" | cut -c 14-) || true
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500252 fi
253
Isaac Kurthc53fcca2022-02-02 15:24:33 -0600254 mapfile -t array <<< "${vols}"
255 for (( index=0; index<${#array[@]}; index++ )); do
Patrick Williams780c9302022-12-08 06:34:04 -0600256 ubi_remove "${array[index]}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500257 done
258}
259
Patrick Williams780c9302022-12-08 06:34:04 -0600260function 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500271 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500272}
273
Patrick Williams780c9302022-12-08 06:34:04 -0600274function remount_ubi() {
275 bmcmtd="$(findmtd "bmc")"
276 altbmcmtd="$(findmtd "alt-bmc")"
277 mtds="${bmcmtd: -1}","${altbmcmtd: -1}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500278
Patrick Williams780c9302022-12-08 06:34:04 -0600279 rootubi="$(findrootubi)"
280 rootname="$(findname "${rootubi}")"
Adriana Kobylak1e81f232022-01-18 22:28:47 +0000281
Patrick Williams780c9302022-12-08 06:34:04 -0600282 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:]')"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500294
Patrick Williams780c9302022-12-08 06:34:04 -0600295 if [[ ${name} == rofs-* ]]; then
296 if [[ "${name}" == "${rootname}" ]]; then
297 mountdir="/media/${name}-functional"
298 else
299 mountdir="/media/${name}"
300 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500301
Patrick Williams780c9302022-12-08 06:34:04 -0600302 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500313 done
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500314
Patrick Williams780c9302022-12-08 06:34:04 -0600315 set_wdt2bite
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500316}
317
Patrick Williams780c9302022-12-08 06:34:04 -0600318function 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
Lei YU63769642021-12-10 16:15:04 +0800329}
330
Patrick Williams780c9302022-12-08 06:34:04 -0600331function umount_static_alt() {
332 altFs=$1
333 altFsMount="/run/media/${altFs}"
334 umount "${altFsMount}"
Lei YUb5171ac2021-12-16 18:36:27 +0800335}
336
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500337# Read the current env variable and set it on the alternate boot env
Patrick Williams780c9302022-12-08 06:34:04 -0600338function 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}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500342}
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.
Patrick Williams780c9302022-12-08 06:34:04 -0600347function copy_ubiblock_to_alt() {
348 value="$(fw_printenv -n ubiblock)"
349 bmcNum="$(findmtdnum "bmc")"
350 altNum="$(findmtdnum "alt-bmc")"
351 replaceAlt="${value/${altNum},/${bmcNum},}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500352
Patrick Williams780c9302022-12-08 06:34:04 -0600353 if [[ "${value}" == "${replaceAlt}" ]]; then
354 replaceBmc="${value/${bmcNum},/${altNum},}"
355 value=${replaceBmc}
356 else
357 value=${replaceAlt}
358 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500359
Patrick Williams780c9302022-12-08 06:34:04 -0600360 fw_setenv -c /etc/alt_fw_env.config ubiblock "${value}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500361}
362
Patrick Williams780c9302022-12-08 06:34:04 -0600363function copy_root_to_alt() {
364 value="$(fw_printenv -n root)"
365 bmcNum="$(findmtdnum "bmc")"
366 altNum="$(findmtdnum "alt-bmc")"
367 replaceAlt="${value/${altNum}_/${bmcNum}_}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500368
Patrick Williams780c9302022-12-08 06:34:04 -0600369 if [[ "${value}" == "${replaceAlt}" ]]; then
370 replaceBmc="${value/${bmcNum}_/${altNum}_}"
371 value=${replaceBmc}
372 else
373 value=${replaceAlt}
374 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500375
Patrick Williams780c9302022-12-08 06:34:04 -0600376 fw_setenv -c /etc/alt_fw_env.config root "${value}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500377}
378
Patrick Williams780c9302022-12-08 06:34:04 -0600379function ubi_setenv() {
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500380 # 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
Isaac Kurthc53fcca2022-02-02 15:24:33 -0600390 if [[ "${currentValue}" != "${value}" ]]; then
Patrick Williams780c9302022-12-08 06:34:04 -0600391 fw_setenv "$varName" "$value"
392 fw_setenv "$varName" "$value"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500393 fi
394 else
395 fw_setenv "$variable"
396 fw_setenv "$variable"
397 fi
398}
399
Patrick Williams780c9302022-12-08 06:34:04 -0600400function mtd_write() {
401 flashmtd="$(findmtd "${reqmtd}")"
402 img="/tmp/images/${version}/${imgfile}"
403 flashcp -v "${img}" /dev/"${flashmtd}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500404}
405
Patrick Williams780c9302022-12-08 06:34:04 -0600406function backup_env_vars() {
407 copy_env_var_to_alt kernelname
408 copy_ubiblock_to_alt
409 copy_root_to_alt
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500410}
411
Patrick Williams780c9302022-12-08 06:34:04 -0600412function 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}"
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 rebootguardenable() {
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 mkdir -p ${dir}"${unit}".target.d
436 echo -e "[Unit]\nRefuseManualStart=yes" >> ${dir}"${unit}".target.d/${file}
437 done
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500438}
439
440#TODO: Replace the implementation with systemd-inhibitors lock
441# once systemd/systemd#949 is resolved
Patrick Williams780c9302022-12-08 06:34:04 -0600442function rebootguarddisable() {
443 dir="/run/systemd/system/"
444 file="reboot-guard.conf"
445 units=("reboot" "poweroff" "halt")
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500446
Patrick Williams780c9302022-12-08 06:34:04 -0600447 for unit in "${units[@]}"; do
448 rm -rf ${dir}"${unit}".target.d/${file}
449 done
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500450}
451
452# Create a copy in the alt mtd
Patrick Williams780c9302022-12-08 06:34:04 -0600453function 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500462}
463
464# Copy contents of one MTD device to another
Patrick Williams780c9302022-12-08 06:34:04 -0600465function mtd_copy() {
466 in=$1
467 out=$2
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500468
Patrick Williams780c9302022-12-08 06:34:04 -0600469 # Must erase MTD first to prevent corruption
470 flash_eraseall "${out}"
471 dd if="${in}" of="${out}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500472}
473
Patrick Williams780c9302022-12-08 06:34:04 -0600474function mirroruboot() {
475 bmc="$(findmtd "u-boot")"
476 bmcdev="/dev/${bmc}"
477 alt="$(findmtd "alt-u-boot")"
478 altdev="/dev/${alt}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500479
Patrick Williams780c9302022-12-08 06:34:04 -0600480 checksum_bmc="$(md5sum "${bmcdev}")"
481 checksum_bmc="${checksum_bmc% *}"
482 checksum_alt="$(md5sum "${altdev}")"
483 checksum_alt="${checksum_alt% *}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500484
Patrick Williams780c9302022-12-08 06:34:04 -0600485 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}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500490
Patrick Williams780c9302022-12-08 06:34:04 -0600491 echo "Mirroring U-boot to alt chip"
492 mtd_copy "${bmcdev}" "${altdev}"
493 mtd_copy "${bmcenvdev}" "${altenvdev}"
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500494
Patrick Williams780c9302022-12-08 06:34:04 -0600495 copy_ubiblock_to_alt
496 copy_root_to_alt
497 fi
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500498}
499
Adriana Kobylak62f38202020-09-29 13:04:25 -0500500# 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.
Patrick Williams780c9302022-12-08 06:34:04 -0600503function cmp_uboot() {
504 device="$1"
505 image="$2"
Adriana Kobylak62f38202020-09-29 13:04:25 -0500506
Patrick Williams780c9302022-12-08 06:34:04 -0600507 # 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}"
Adriana Kobylak62f38202020-09-29 13:04:25 -0500516
Patrick Williams780c9302022-12-08 06:34:04 -0600517 if [ "${imgSum}" == "${devSum}" ]; then
518 echo "0";
519 else
520 echo "1";
521 fi
Adriana Kobylak62f38202020-09-29 13:04:25 -0500522}
523
Adriana Kobylak70f5bc02020-05-13 14:08:14 -0500524# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b.
Adriana Kobylak34124352020-05-22 09:40:40 -0500525# Return the label (a or b) for the running partition.
Patrick Williams780c9302022-12-08 06:34:04 -0600526function 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}*}"
Adriana Kobylak5312d852020-07-18 09:49:34 -0500532
Patrick Williams780c9302022-12-08 06:34:04 -0600533 # 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
Adriana Kobylak34124352020-05-22 09:40:40 -0500541}
542
543# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b.
Adriana Kobylak70f5bc02020-05-13 14:08:14 -0500544# Return the label (a or b) for the non-running partition.
Patrick Williams780c9302022-12-08 06:34:04 -0600545function 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 ""
Adriana Kobylakd148b4f2020-08-27 10:18:49 -0500553 fi
Adriana Kobylak70f5bc02020-05-13 14:08:14 -0500554}
555
Patrick Williams780c9302022-12-08 06:34:04 -0600556function mmc_mount() {
557 primaryId="$(mmc_get_primary_label)"
558 secondaryId="$(mmc_get_secondary_label)"
Adriana Kobylak8c5209d2020-07-12 13:35:47 -0500559
Patrick Williams780c9302022-12-08 06:34:04 -0600560 primaryDir="${mediaDir}/rofs-${primaryId}-functional"
561 secondaryDir="${mediaDir}/rofs-${secondaryId}"
562
Adriana Kobylakdcfadad2023-05-23 20:41:38 +0000563 # 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
Patrick Williams780c9302022-12-08 06:34:04 -0600570 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
Adriana Kobylakdedcb9a2023-06-02 09:05:54 -0500606 # Update hostfw. The remove function doesn't touch the hostfw image, so
607 # need to unmount and delete it prior to updating it.
Patrick Williams780c9302022-12-08 06:34:04 -0600608 if [ -f "${imgpath}"/"${version}"/image-hostfw ]; then
609 # Remove patches
Adriana Kobylakdedcb9a2023-06-02 09:05:54 -0500610 hostfw_alt="hostfw/alternate"
611 patchdir="/usr/local/share/${hostfw_alt}"
Patrick Williams780c9302022-12-08 06:34:04 -0600612 if [ -d "${patchdir}" ]; then
613 rm -rf "${patchdir:?}"/*
614 fi
Adriana Kobylakdedcb9a2023-06-02 09:05:54 -0500615 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
Patrick Williams780c9302022-12-08 06:34:04 -0600619 hostfwdir=$(grep "hostfw " /proc/mounts | cut -d " " -f 2)
Adriana Kobylakdedcb9a2023-06-02 09:05:54 -0500620 rm -f "${hostfwdir}/hostfw-${flashid}"
Patrick Williams780c9302022-12-08 06:34:04 -0600621 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
Adriana Kobylak70f5bc02020-05-13 14:08:14 -0500640}
641
Adriana Kobylak34124352020-05-22 09:40:40 -0500642# Set the requested version as primary for the BMC to boot from upon reboot.
Patrick Williams780c9302022-12-08 06:34:04 -0600643function mmc_setprimary() {
644 # Point root to the flashid of the requested BMC rootfs.
645 fw_setenv bootside "${flashid}"
Adriana Kobylak34124352020-05-22 09:40:40 -0500646}
647
Lakshmi Yadlapati87c5b5b2022-11-15 18:14:12 -0600648function 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
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500675case "$1" in
Patrick Williams780c9302022-12-08 06:34:04 -0600676 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 ;;
Lakshmi Yadlapati87c5b5b2022-11-15 18:14:12 -0600755 mmc-mirroruboot)
756 mmc_mirroruboot
757 ;;
Patrick Williams780c9302022-12-08 06:34:04 -0600758 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 ;;
Adriana Kobylak9cbfa2e2019-04-25 14:02:37 -0500768esac