1#!/bin/bash 2# Copyright 2021 The ChromiumOS Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5# 6# A script to facilitate rescue update of GSC targets, supports both Cr50 and 7# Ti50. 8# 9# The two input parameters are the file name of the full binary mage (both ROs 10# and both RWs) and the name of the UART device connected to the GSC console. 11# 12# The script carves out the RW_A from the binary, converts it into hex format 13# and starts the rescue utility to send the RW to the chip. The user is 14# supposed to reset the chip to trigger the rescue session. 15# 16# If invoked with RESCUE environment variable set to a path, the script will try 17# to use the rescue binary at that path. 18# 19# If invoked with nonempty NOCLEAN environment variable, the script preserves 20# the hex RW image it creates. 21# 22# If invoked with nonempty EARLY environment variable, the script passes the 23# --early option to rescue. 24 25TMPD="$(mktemp -d "/tmp/$(basename "$0").XXXXX")" 26 27for r in ${RESCUE} rescue cr50-rescue; do 28 if type "${r}" > /dev/null 2>&1; then 29 RESCUE="${r}" 30 break 31 fi 32done 33 34if [[ -z ${RESCUE} ]]; then 35 echo "rescue utility is not found, can not continue" >&2 36 exit 1 37fi 38if [[ -z "${NOCLEAN}" ]]; then 39 trap 'rm -rf "${TMPD}"' EXIT 40fi 41 42# --early could help to improve success rate depending on setup. 43early='' 44if [[ -n "${EARLY}" ]]; then 45 early='--early' 46fi 47 48dest_hex="${TMPD}/rw.hex" 49dest_bin="${TMPD}/rw.bin" 50errorf="${TMPD}/error" 51 52usage() { 53 cat >&2 <<EOF 54Two parameters are required, the name of the valid GSC binary image 55and the name of the H1 console tty device 56EOF 57 exit 1 58} 59 60# Determine RW_A offset of the Ti50 image. The header magic pattern is used to 61# find headers in the binary. 62rw_offset() { 63 local src 64 local base 65 66 src="$1" 67 # The second grep term filters out the 'fake' cryptolib header, which does 68 # not contain a valid signature, the signature field is filled with SSSSS 69 # (0x53...). 70 base=$(/usr/bin/od -Ax -t x1 -v "${src}" | 71 grep -E '^....00 fd ff ff ff' | grep -v '00 fd ff ff ff 53 53 53' | 72 head -2 | 73 tail -1 | 74 sed 's/ .*//') 75 printf '%d' "0x${base}" 76} 77 78if [[ $# != 2 ]]; then 79 usage 80fi 81 82source="$1" 83device="$2" 84 85if [[ ! -f ${source} ]]; then 86 usage 87fi 88 89if [[ ${device} != /dev/* || ! -e ${device} ]]; then 90 usage 91fi 92 93pid="$(lsof "${device}" | awk -v v="${device}" '/v/ {print $2}')" 94if [[ -n ${pid} ]]; then 95 echo -n "${device} is in use, will try to kill process ${pid} " 96 deadline=$(( $(date '+%s') + 5 )) 97 kill -HUP "${pid}" 98 while [[ $(date '+%s') -le ${deadline} ]]; do 99 echo -n '.' 100 if [[ -z $(lsof "${device}") ]]; then 101 break 102 fi 103 done 104 if [[ -n $(lsof "${device}") ]]; then 105 printf "\nFailed to kill process using %s\n" "${device}" >&2 106 exit 1 107 fi 108 echo " succeeded" 109fi 110 111# Use Cr50 or Ti50 options base on the file size. 112case "$(stat -c '%s' "${source}")" in 113 (524288) 114 skip=16384 115 count=233472 116 chip_extension='' 117 addr=0x44000 118 ;; 119 (1048576) 120 skip=$(rw_offset "${source}") 121 count=$(( 1048576/2 - "${skip}" )) 122 chip_extension='--dauntless' 123 addr="$(printf '0x%x' $(( 0x80000 + "${skip}" )))" 124 ;; 125 (*) 126 echo "Unrecognized input file" >&2 127 exit 1 128 ;; 129esac 130 131# Carve out RW_A in binary form. 132if ! dd if="${source}" of="${dest_bin}" skip="${skip}" count="${count}" bs=1 \ 133 2>"${errorf}"; then 134 echo "Failed to carve out the RW bin:" >&2 135 cat "${errorf}" >&2 136 exit 1 137fi 138echo "carved out binary ${dest_bin} mapped to ${addr}" 139 140# Convert binary to hex. 141if ! objcopy -I binary -O ihex --change-addresses "${addr}" \ 142 "${dest_bin}" "${dest_hex}"; then 143 echo "Failed to convert to hex" >&2 144 exit 1 145fi 146echo "converted to ${dest_hex}, waiting for target reset" 147 148echo "${RESCUE}" "${chip_extension}" -d "${device}" "${early}" -v -i \ 149 "${dest_hex}" 150"${RESCUE}" "${chip_extension}" -d "${device}" "${early}" -v -i "${dest_hex}" 151