xref: /openbmc/openpower-pnor-code-mgmt/ubi/obmc-flash-bios (revision fc886cabfe3699bfe70eee0359eb62c88f5dec17)
1#!/bin/bash
2
3# Get the mtd device number (mtdX)
4findmtd() {
5  m="$(grep -xl "$1" /sys/class/mtd/*/name)"
6  m="${m%/name}"
7  m="${m##*/}"
8  echo "${m}"
9}
10
11# Get the ubi device number (ubiX_Y)
12findubi() {
13  u="$(grep -xl "$1" /sys/class/ubi/ubi?/subsystem/ubi*/name)"
14  u="${u%/name}"
15  u="${u##*/}"
16  echo "${u}"
17}
18
19# Get the mount information
20is_mounted() {
21  grep -q "$1" /proc/mounts
22  return $?
23}
24
25# Attach the pnor mtd device to ubi.
26attach_ubi() {
27  pnormtd="$(findmtd pnor)"
28  pnor="${pnormtd#mtd}"
29  pnordev="/dev/mtd${pnor}"
30
31  if [ -d "/sys/class/ubi/ubi${pnor}" ]; then
32    # Already attached
33    return 0
34  fi
35
36  ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}"
37  rc=$?
38  if [ ${rc} -ne 0 ]; then
39    # Check the pnor mtd device is formatted as ubi by reading the first 3 byes,
40    # which should be the ascii chars 'UBI'
41    magic="$(hexdump -C -n 3 "${pnordev}")"
42    if [[ "${magic}" =~ "UBI" ]]; then
43      # Device already formatted as ubi, ubiattach failed for some other reason
44      return ${rc}
45    else
46      # Format device as ubi
47      echo "Starting ubiformat ${pnordev}"
48      ubiformat "${pnordev}" -y -q
49      # Retry the ubiattach
50      ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}"
51    fi
52  fi
53}
54
55mount_squashfs() {
56  pnormtd="$(findmtd pnor)"
57  ubidev="/dev/ubi${pnormtd#mtd}"
58  mountdir="/media/${name}"
59  vol="$(findubi "${name}")"
60  img="/tmp/images/${version}/pnor.xz.squashfs"
61  # shellcheck disable=SC2012 # ls provides the size in human-readable form
62  filesize="$(ls -sh "$img" | awk -F " " '{print $1}')"
63
64  if is_mounted "${name}"; then
65    echo "${name} is already mounted."
66    return 0
67  fi
68
69  if [ -n "${vol}" ]; then
70    ubirmvol "${ubidev}" -N "${name}"
71  fi
72
73  if [ ! -d "${mountdir}" ]; then
74    mkdir "${mountdir}"
75  fi
76
77  # Set size of read-only partition equal to pnor.xz.squashfs
78  ubimkvol "${ubidev}" -N "${name}" -s "${filesize}"KiB --type=static
79  if ! vol="$(findubi "${name}")"; then
80    echo "Unable to create RO volume!"
81    return 1
82  fi
83
84  ubidevid="${vol#ubi}"
85  if ! ubiupdatevol "/dev/ubi${ubidevid}" "${img}"; then
86    echo "Unable to update RO volume!"
87    return 1
88  fi
89
90  if ! ubiblock --create "/dev/ubi${ubidevid}"; then
91    echo "Unable to create UBI block for RO volume!"
92    return 1
93  fi
94
95  if ! mount -t squashfs -o ro "/dev/ubiblock${ubidevid}" "${mountdir}"; then
96    echo "Unable to mount RO volume!"
97    return 1
98  fi
99}
100
101mount_ubi() {
102  pnormtd="$(findmtd pnor)"
103  pnor="${pnormtd#mtd}"
104  ubidev="/dev/ubi${pnor}"
105  pnordev="/dev/mtd${pnor}"
106
107  if [[ "${name}" == "pnor-patch" ]]; then
108    if [[ "$(fw_printenv fieldmode 2>/dev/null)" == "fieldmode=true" ]]; then
109      return 0
110    fi
111    if [[ ! "$(hexdump -C -n 3 "${pnordev}")" =~ "UBI" ]]; then
112      return 0
113    fi
114    mountdir="/usr/local/share/pnor"
115  else
116    mountdir="/media/${name}"
117  fi
118
119  if [[ "${name}" == "pnor-prsv" ]]; then
120    size="2MiB"
121  else
122    size="16MiB"
123  fi
124
125  if [ ! -d "${mountdir}" ]; then
126    mkdir -p "${mountdir}"
127  fi
128
129  vol="$(findubi "${name}")"
130  if [ -z "${vol}" ]; then
131    ubimkvol "${ubidev}" -N "${name}" -s "${size}"
132  fi
133
134  if ! is_mounted "${name}"; then
135    mountdev="ubi${pnor}:${name}"
136    mount -t ubifs "${mountdev}" "${mountdir}"
137  fi
138}
139
140umount_ubi() {
141  pnormtd="$(findmtd pnor)"
142  pnor="${pnormtd#mtd}"
143  ubidev="/dev/ubi${pnor}"
144  mountdir="/media/${name}"
145
146  if is_mounted "${name}"; then
147    umount "${mountdir}"
148  fi
149
150  vol="$(findubi "${name}")"
151  id="${vol##*_}"
152  if [ -n "${id}" ]; then
153    ubirmvol "${ubidev}" -n "${id}"
154  fi
155
156  if [ -d "${mountdir}" ]; then
157    rm -r "${mountdir}"
158  fi
159}
160
161remount_ubi() {
162  pnormtd="$(findmtd pnor)"
163  pnor="${pnormtd#mtd}"
164  pnordev="/dev/mtd${pnor}"
165
166  # Re-Attach the pnor mtd device to ubi
167  if [[ $(hexdump -C -n 3 "${pnordev}") =~ "UBI" ]]; then
168    ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}"
169  else
170    # Device not formatted as ubi.
171    return 0
172  fi
173
174  # Get information on all ubi volumes
175  ubinfo=$(ubinfo -d "${pnor}")
176  presentVolumes=${ubinfo##*:}
177  IFS=', ' read -r -a array <<< "$presentVolumes"
178  for element in "${array[@]}";
179  do
180    elementProperties=$(ubinfo -d "$pnor" -n "$element")
181    # Get ubi volume name by getting rid of additional properties
182    name=${elementProperties#*Name:}
183    name="${name%Character*}"
184    name="$(echo -e "${name}" | tr -d '[:space:]')"
185
186    if [[ ${name} == pnor-prsv ]] || [[ ${name} == pnor-rw* ]] || [[ ${name} == pnor-ro* ]]; then
187      mountdir="/media/${name}"
188      if [ ! -d "${mountdir}" ]; then
189        mkdir -p "${mountdir}"
190      fi
191
192      if [[ ${name} == pnor-ro* ]]
193      then
194        ubiblock --create "/dev/ubi${pnor}_${element}"
195        mount -t squashfs -o ro "/dev/ubiblock${pnor}_${element}" "${mountdir}"
196      else
197        mount -t ubifs "ubi${pnor}:${name}" "${mountdir}"
198      fi
199    fi
200  done
201}
202
203ubi_cleanup() {
204    # When ubi_cleanup is run, it expects one or no active version.
205    activeVersion=$(busctl --list --no-pager tree \
206            org.open_power.Software.Host.Updater | \
207            grep /xyz/openbmc_project/software/ | tail -c 9)
208
209    if [[ -z "$activeVersion" ]]; then
210        vols=$(ubinfo -a | grep -e "pnor-ro-" -e "pnor-rw-" | cut -c 14-)
211        mapfile -t array <<< "${vols}"
212    else
213        vols=$(ubinfo -a | grep -e "pnor-ro-" -e "pnor-rw-" | \
214                grep -v "$activeVersion" | cut -c 14-)
215        mapfile -t array <<< "${vols}"
216    fi
217
218    for (( index=0; index<${#array[@]}; index++ )); do
219         name=${array[index]}
220         umount_ubi
221    done
222}
223
224case "$1" in
225  ubiattach)
226    attach_ubi
227    ;;
228  squashfsmount)
229    name="$2"
230    version="$3"
231    mount_squashfs
232    ;;
233  ubimount)
234    name="$2"
235    mount_ubi
236    ;;
237  ubiumount)
238    name="$2"
239    umount_ubi
240    ;;
241  ubiremount)
242    remount_ubi
243    ;;
244  ubicleanup)
245    ubi_cleanup
246    ;;
247  *)
248    echo "Invalid argument"
249    exit 1
250    ;;
251esac
252rc=$?
253if [ ${rc} -ne 0 ]; then
254  echo "$0: error ${rc}"
255  exit ${rc}
256fi
257