1#!/bin/sh 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 filesize="$(ls -sh $img | awk -F " " {'print $1'})" 62 63 if is_mounted "${name}"; then 64 echo "${name} is already mounted." 65 return 0 66 fi 67 68 if [ ! -z "${vol}" ]; then 69 ubirmvol "${ubidev}" -N "${name}" 70 fi 71 72 if [ ! -d "${mountdir}" ]; then 73 mkdir "${mountdir}" 74 fi 75 76 # Set size of read-only partition equal to pnor.xz.squashfs 77 ubimkvol "${ubidev}" -N "${name}" -s "${filesize}"KiB --type=static 78 vol="$(findubi "${name}")" 79 80 if [ $? != 0 ]; then 81 echo "Unable to create RO volume!" 82 return 1 83 fi 84 85 ubidevid="${vol#ubi}" 86 ubiupdatevol "/dev/ubi${ubidevid}" "${img}" 87 88 if [ $? != 0 ]; then 89 echo "Unable to update RO volume!" 90 return 1 91 fi 92 93 ubiblock --create "/dev/ubi${ubidevid}" 94 95 if [ $? != 0 ]; then 96 echo "Unable to create UBI block for RO volume!" 97 return 1 98 fi 99 100 mount -t squashfs -o ro "/dev/ubiblock${ubidevid}" "${mountdir}" 101 102 if [ $? != 0 ]; then 103 echo "Unable to mount RO volume!" 104 return 1 105 fi 106} 107 108mount_ubi() { 109 pnormtd="$(findmtd pnor)" 110 pnor="${pnormtd#mtd}" 111 ubidev="/dev/ubi${pnor}" 112 pnordev="/dev/mtd${pnor}" 113 114 if [[ "${name}" == "pnor-patch" ]]; then 115 if [[ "$(fw_printenv fieldmode 2>/dev/null)" == "fieldmode=true" ]]; then 116 return 0 117 fi 118 if [[ ! "$(hexdump -C -n 3 ${pnordev})" =~ "UBI" ]]; then 119 return 0 120 fi 121 mountdir="/usr/local/share/pnor" 122 else 123 mountdir="/media/${name}" 124 fi 125 126 if [[ "${name}" == "pnor-prsv" ]]; then 127 size="2MiB" 128 else 129 size="16MiB" 130 fi 131 132 if [ ! -d "${mountdir}" ]; then 133 mkdir -p "${mountdir}" 134 fi 135 136 vol="$(findubi "${name}")" 137 if [ -z "${vol}" ]; then 138 ubimkvol "${ubidev}" -N "${name}" -s "${size}" 139 fi 140 141 if ! is_mounted "${name}"; then 142 mountdev="ubi${pnor}:${name}" 143 mount -t ubifs "${mountdev}" "${mountdir}" 144 fi 145} 146 147umount_ubi() { 148 pnormtd="$(findmtd pnor)" 149 pnor="${pnormtd#mtd}" 150 ubidev="/dev/ubi${pnor}" 151 mountdir="/media/${name}" 152 153 if is_mounted "${name}"; then 154 umount "${mountdir}" 155 fi 156 157 vol="$(findubi "${name}")" 158 id="${vol##*_}" 159 if [ -n "${id}" ]; then 160 ubirmvol "${ubidev}" -n "${id}" 161 fi 162 163 if [ -d "${mountdir}" ]; then 164 rm -r "${mountdir}" 165 fi 166} 167 168remount_ubi() { 169 pnormtd="$(findmtd pnor)" 170 pnor="${pnormtd#mtd}" 171 pnordev="/dev/mtd${pnor}" 172 173 # Re-Attach the pnor mtd device to ubi 174 if [[ $(hexdump -C -n 3 ${pnordev}) =~ "UBI" ]]; then 175 ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}" 176 else 177 # Device not formatted as ubi. 178 return 0 179 fi 180 181 # Get information on all ubi volumes 182 ubinfo=$(ubinfo -d ${pnor}) 183 presentVolumes=${ubinfo##*:} 184 IFS=', ' read -r -a array <<< "$presentVolumes" 185 for element in ${array[@]}; 186 do 187 elementProperties=$(ubinfo -d $pnor -n $element) 188 # Get ubi volume name by getting rid of additional properties 189 name=${elementProperties#*Name:} 190 name="${name%Character*}" 191 name="$(echo -e "${name}" | tr -d '[:space:]')" 192 193 if [[ ${name} == pnor-prsv ]] || [[ ${name} == pnor-rw* ]] || [[ ${name} == pnor-ro* ]]; then 194 mountdir="/media/${name}" 195 if [ ! -d "${mountdir}" ]; then 196 mkdir -p "${mountdir}" 197 fi 198 199 if [[ ${name} == pnor-ro* ]] 200 then 201 ubiblock --create /dev/ubi${pnor}_${element} 202 mount -t squashfs -o ro "/dev/ubiblock${pnor}_${element}" "${mountdir}" 203 else 204 mount -t ubifs "ubi${pnor}:${name}" "${mountdir}" 205 fi 206 fi 207 done 208} 209 210ubi_cleanup() { 211 # When ubi_cleanup is run, it expects one or no active version. 212 activeVersion=$(busctl --list --no-pager tree \ 213 org.open_power.Software.Host.Updater | \ 214 grep /xyz/openbmc_project/software/ | tail -c 9) 215 216 if [[ -z "$activeVersion" ]]; then 217 vols=$(ubinfo -a | grep -e "pnor-ro-" -e "pnor-rw-" | cut -c 14-) 218 vols=(${vols}) 219 else 220 vols=$(ubinfo -a | grep -e "pnor-ro-" -e "pnor-rw-" | \ 221 grep -v "$activeVersion" | cut -c 14-) 222 vols=(${vols}) 223 fi 224 225 for (( index=0; index<${#vols[@]}; index++ )); do 226 name=${vols[index]} 227 umount_ubi 228 done 229} 230 231case "$1" in 232 ubiattach) 233 attach_ubi 234 ;; 235 squashfsmount) 236 name="$2" 237 version="$3" 238 mount_squashfs 239 ;; 240 ubimount) 241 name="$2" 242 mount_ubi 243 ;; 244 ubiumount) 245 name="$2" 246 umount_ubi 247 ;; 248 ubiremount) 249 remount_ubi 250 ;; 251 ubicleanup) 252 ubi_cleanup 253 ;; 254 *) 255 echo "Invalid argument" 256 exit 1 257 ;; 258esac 259rc=$? 260if [ ${rc} -ne 0 ]; then 261 echo "$0: error ${rc}" 262 exit ${rc} 263fi 264