summaryrefslogtreecommitdiff
path: root/util/brescue.sh
diff options
context:
space:
mode:
Diffstat (limited to 'util/brescue.sh')
-rwxr-xr-xutil/brescue.sh121
1 files changed, 121 insertions, 0 deletions
diff --git a/util/brescue.sh b/util/brescue.sh
new file mode 100755
index 0000000000..163f6ed6b8
--- /dev/null
+++ b/util/brescue.sh
@@ -0,0 +1,121 @@
+#!/bin/bash
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# A script to facilitate rescue update of GSC targets, supports both Cr50 and
+# Ti50.
+#
+# The two input parameters are the file name of the full binary mage (both ROs
+# and both RWs) and the name of the UART device connected to the GSC console.
+#
+# The script carves out the RW_A from the binary, converts it into hex format
+# and starts the rescue utility to send the RW to the chip. The user is
+# supposed to reset the chip to trigger the rescue session.
+#
+# In invoked with nonempty NOCLEAN environment variable the script preserves
+# the hex RW image it creates.
+
+TMPD="$(mktemp -d "/tmp/$(basename "$0").XXXXX")"
+
+RESCUE=
+for r in rescue cr50-rescue; do
+ if type "${r}" > /dev/null 2>&1; then
+ RESCUE="${r}"
+ break
+ fi
+done
+
+if [[ -z ${RESCUE} ]]; then
+ echo "rescue utility is not found, can not continue" >&2
+ exit 1
+fi
+if [[ -z "${NOCLEAN}" ]]; then
+ trap 'rm -rf "${TMPD}"' EXIT
+fi
+
+dest_hex="${TMPD}/rw.hex"
+dest_bin="${TMPD}/rw.bin"
+errorf="${TMPD}/error"
+
+usage() {
+ cat >&2 <<EOF
+Two parameters are required, the name of the valid GSC binary image
+and the name of the H1 console tty device
+EOF
+ exit 1
+}
+
+# Determine RW_A offset of the Ti50 image. The header magic pattern is used to
+# find headers in the binary.
+rw_offset() {
+ local src
+ local base
+
+ src="$1"
+ base=$(/usr/bin/od -Ax -t x1 -v "${src}" |
+ grep -E '^....00 fd ff ff ff' |
+ head -2 |
+ tail -1 |
+ sed 's/ .*//')
+ printf '%d' "0x${base}"
+}
+
+if [[ $# != 2 ]]; then
+ usage
+fi
+
+source="$1"
+device="$2"
+
+if [[ ! -f ${source} ]]; then
+ usage
+fi
+
+if [[ ${device} != /dev/* || ! -e ${device} ]]; then
+ usage
+fi
+
+if [[ -n $(lsof "${device}" 2>/dev/null) ]]; then
+ echo "${device} is in use, make sure it is available" >&2
+ exit 1
+fi
+
+# Use Cr50 or Ti50 options base on the file size.
+case "$(stat -c '%s' "${source}")" in
+ (524288)
+ skip=16384
+ count=233472
+ chip_extension=''
+ addr=0x44000
+ ;;
+ (1048576)
+ skip=$(rw_offset "${source}")
+ count=$(( 1048576/2 - "${skip}" ))
+ chip_extension='--dauntless'
+ addr="$(printf '0x%x' $(( 0x80000 + "${skip}" )))"
+ ;;
+ (*)
+ echo "Unrecognized input file" >&2
+ exit 1
+ ;;
+esac
+
+# Carve out RW_A in binary form.
+if ! dd if="${source}" of="${dest_bin}" skip="${skip}" count="${count}" bs=1 \
+ 2>"${errorf}"; then
+ echo "Failed to carve out the RW bin:" >&2
+ cat "${errorf}" >&2
+ exit 1
+fi
+echo "carved out binary ${dest_bin} mapped to ${addr}"
+
+# Convert binary to hex.
+if ! objcopy -I binary -O ihex --change-addresses "${addr}" \
+ "${dest_bin}" "${dest_hex}"; then
+ echo "Failed to convert to hex" >&2
+ exit 1
+fi
+echo "converted to ${dest_hex}, waiting for target reset"
+
+"${RESCUE}" "${chip_extension}" -d "${device}" -v -i "${dest_hex}"