1#!/bin/bash 2# 3# Copyright 2024 The ChromiumOS Authors 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7SCRIPT_BASE="$(dirname "$0")" 8. "$SCRIPT_BASE/common_minimal.sh" 9load_shflags || exit 1 10 11FLAGS_HELP=" 12Swap the EC RW (ecrw) within an AP firmware (BIOS) image. 13" 14 15# Flags. 16DEFINE_string image "" "The AP firmware file (e.g 'image-steelix.bin') to swap out ecrw" i 17DEFINE_string ec "" "The EC firmware file (e.g 'ec.bin')" e 18 19# Parse command line. 20FLAGS "$@" || exit 1 21eval set -- "${FLAGS_ARGV}" 22 23# Only after this point should you enable `set -e` as shflags does not work 24# when that is turned on first. 25set -e 26 27FMAP_REGIONS=( "FW_MAIN_A" "FW_MAIN_B" ) 28CBFS_ECRW_NAME="ecrw" 29CBFS_ECRW_HASH_NAME="ecrw.hash" 30CBFS_ECRW_VERSION_NAME="ecrw.version" 31CBFS_ECRW_CONFIG_NAME="ecrw.config" 32 33swap_ecrw() { 34 local ap_file=$1 35 local ec_file=$2 36 local temp_dir 37 local info 38 local ecrw_file 39 local ecrw_hash_file 40 local ecrw_version_file 41 local ecrw_comp_type 42 local ecrw_version 43 temp_dir=$(mktemp -d) 44 ecrw_file="${temp_dir}/ecrw" 45 futility dump_fmap -x "${ec_file}" "RW_FW:${ecrw_file}" >/dev/null 46 info "EC RW extracted to ${ecrw_file}" 47 48 ecrw_hash_file="${temp_dir}/ecrw.hash" 49 openssl dgst -sha256 -binary "${ecrw_file}" > "${ecrw_hash_file}" 50 info "EC RW hash saved to ${ecrw_hash_file}" 51 52 ecrw_version_file="${temp_dir}/ecrw.version" 53 futility dump_fmap -x "${ec_file}" "RW_FWID:${ecrw_version_file}" >/dev/null 54 55 for region in "${FMAP_REGIONS[@]}" 56 do 57 info="$(cbfstool "${ap_file}" print -r "${region}" -k -v \ 58 | grep -m 1 "^${CBFS_ECRW_NAME}\s")" 59 ecrw_comp_type="$(cut -f7- <<< "${info}" | grep -o '\<comp\>:\w*' \ 60 | cut -d: -f2)" 61 ecrw_comp_type=${ecrw_comp_type:-none} 62 cbfstool "${ap_file}" remove -r "${region}" -n "${CBFS_ECRW_NAME}" 63 cbfstool "${ap_file}" remove -r "${region}" -n "${CBFS_ECRW_HASH_NAME}" 64 cbfstool "${ap_file}" remove -r "${region}" -n "${CBFS_ECRW_VERSION_NAME}" \ 65 || warn "${CBFS_ECRW_VERSION_NAME} not found, but will be added" 66 # TODO(b/307788351): Update ecrw.config. Right now the config info cannot 67 # be obtained from ec.bin. 68 cbfstool "${ap_file}" remove -r "${region}" \ 69 -n "${CBFS_ECRW_CONFIG_NAME_NAME}" || true 70 cbfstool "${ap_file}" expand -r "${region}" 71 cbfstool "${ap_file}" add -r "${region}" -t raw \ 72 -c "${ecrw_comp_type}" -f "${ecrw_file}" -n "${CBFS_ECRW_NAME}" 73 cbfstool "${ap_file}" add -r "${region}" -t raw \ 74 -c none -f "${ecrw_hash_file}" -n "${CBFS_ECRW_HASH_NAME}" 75 cbfstool "${ap_file}" add -r "${region}" -t raw \ 76 -c none -f "${ecrw_version_file}" -n "${CBFS_ECRW_VERSION_NAME}" 77 done 78 79 local keyset 80 for keyset in /usr/share/vboot/devkeys "${SCRIPT_BASE}/../../tests/devkeys"; do 81 [[ -d "${keyset}" ]] && break 82 done 83 84 # 'futility sign' will call 'cbfstool truncate' if needed 85 futility sign "${ap_file}" --keyset "${keyset}" 86 87 ecrw_version=$(futility update --manifest -e "${ec_file}" \ 88 | jq -r '.default.ec.versions.rw') 89 info "${CBFS_ECRW_NAME} (${ecrw_version}) swapped in ${ap_file}" 90 info "Done" 91} 92 93main() { 94 if [[ -z "${FLAGS_image}" ]]; then 95 flags_help 96 die "-i or --image required." 97 fi 98 if [[ -z "${FLAGS_ec}" ]]; then 99 flags_help 100 die "-e or --ec required." 101 fi 102 103 swap_ecrw "${FLAGS_image}" "${FLAGS_ec}" 104} 105 106main "$@" 107