diff options
author | Hung-Te Lin <hungte@chromium.org> | 2018-08-22 23:13:59 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-08-31 05:22:46 -0700 |
commit | 677b535dda16fe8662d646860ff84b1ed744d902 (patch) | |
tree | 582f3336e01f9f12e68b6353c7f5609afcbd25f6 | |
parent | 09c1c22dff11a588e9f27c57c4574930f2e168dd (diff) | |
download | vboot-677b535dda16fe8662d646860ff84b1ed744d902.tar.gz |
futility: cmd_update: Add '--emulate' option
To help debugging and testing, we may want to run updater against an
image file instead of modifying real system firmware.
The --emulate allows running with all checks and reading, and outputs
to given file.
BUG=chromium:875551
TEST=make futil; futility update -i IMAGE --emulate IMAGE2
tests/futility/run_test_scripts.sh $(pwd)/build/futility
BRANCH=None
Change-Id: Ic52fe60a1468f29245cade70f859513d8d117c9c
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1184953
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | futility/cmd_update.c | 52 | ||||
-rwxr-xr-x | tests/futility/test_update.sh | 17 |
2 files changed, 62 insertions, 7 deletions
diff --git a/futility/cmd_update.c b/futility/cmd_update.c index 0ddaa01b..a3ca288f 100644 --- a/futility/cmd_update.c +++ b/futility/cmd_update.c @@ -26,6 +26,7 @@ static const char * const FMAP_RO_FRID = "RO_FRID", /* flashrom programmers. */ static const char * const PROG_HOST = "host", + * const PROG_EMULATE = "dummy:emulate", * const PROG_EC = "ec", * const PROG_PD = "ec:dev=1"; @@ -36,6 +37,7 @@ enum flashrom_ops { struct firmware_image { const char *programmer; + char *emulation; uint32_t size; uint8_t *data; char *file_name; @@ -51,6 +53,7 @@ struct firmware_section { struct updater_config { struct firmware_image image, image_current; struct firmware_image ec_image, pd_image; + int emulate; }; /* @@ -62,7 +65,7 @@ static int host_flashrom(enum flashrom_ops op, const char *image_path, const char *section_name) { char *command; - const char *op_cmd, *dash_i = "-i", *postfix = ""; + const char *op_cmd, *dash_i = "-i", *postfix = "", *ignore_lock = ""; int r; if (debugging_enabled) @@ -76,6 +79,10 @@ static int host_flashrom(enum flashrom_ops op, const char *image_path, section_name = ""; } + if (strncmp(programmer, PROG_EMULATE, strlen(PROG_EMULATE)) == 0) { + ignore_lock = "--ignore-lock"; + } + switch (op) { case FLASHROM_READ: op_cmd = "-r"; @@ -93,8 +100,9 @@ static int host_flashrom(enum flashrom_ops op, const char *image_path, } /* TODO(hungte) In future we should link with flashrom directly. */ - r = asprintf(&command, "flashrom %s %s -p %s %s %s %s", op_cmd, - image_path, programmer, dash_i, section_name, postfix); + r = asprintf(&command, "flashrom %s %s -p %s %s %s %s %s", op_cmd, + image_path, programmer, dash_i, section_name, ignore_lock, + postfix); if (r == -1) { /* `command` will be not available. */ @@ -212,6 +220,28 @@ static int load_image(const char *file_name, struct firmware_image *image) } /* + * Loads and emulates system firmware by an image file. + * This will set a emulation programmer in image->emulation so flashrom + * can access the file as system firmware storage. + * Returns 0 if success, non-zero if error. + */ +static int emulate_system_image(const char *file_name, + struct firmware_image *image) +{ + if (load_image(file_name, image)) + return -1; + + if (asprintf(&image->emulation, + "%s=VARIABLE_SIZE,image=%s,size=%u", + PROG_EMULATE, file_name, image->size) < 0) { + Error("%s: Failed to allocate buffer for programmer: %s.\n", + __FUNCTION__, file_name); + return -1; + } + return 0; +} + +/* * Loads the active system firmware image (usually from SPI flash chip). * Returns 0 if success, non-zero if error. */ @@ -236,6 +266,7 @@ static void free_image(struct firmware_image *image) free(image->ro_version); free(image->rw_version_a); free(image->rw_version_b); + free(image->emulation); memset(image, 0, sizeof(*image)); } @@ -293,6 +324,7 @@ static void unload_updater_config(struct updater_config *cfg) free_image(&cfg->image_current); free_image(&cfg->ec_image); free_image(&cfg->pd_image); + cfg->emulate = 0; } /* Command line options */ @@ -301,6 +333,7 @@ static struct option const long_opts[] = { {"image", 1, NULL, 'i'}, {"ec_image", 1, NULL, 'e'}, {"pd_image", 1, NULL, 'P'}, + {"emulate", 1, NULL, 'E'}, {"help", 0, NULL, 'h'}, {NULL, 0, NULL, 0}, }; @@ -315,6 +348,9 @@ static void print_help(int argc, char *argv[]) "-i, --image=FILE \tAP (host) firmware image (image.bin)\n" "-e, --ec_image=FILE \tEC firmware image (i.e, ec.bin)\n" " --pd_image=FILE \tPD firmware image (i.e, pd.bin)\n" + "\n" + "Debugging and testing options:\n" + " --emulate=FILE \tEmulate system firmware using file\n" "", argv[0]); } @@ -343,6 +379,16 @@ static int do_update(int argc, char *argv[]) case 'P': errorcnt += load_image(optarg, &cfg.pd_image); break; + case 'E': + cfg.emulate = 1; + errorcnt += emulate_system_image( + optarg, &cfg.image_current); + /* Both image and image_current need emulation. */ + if (!errorcnt) { + cfg.image.emulation = strdup( + cfg.image_current.emulation); + } + break; case 'h': print_help(argc, argv); diff --git a/tests/futility/test_update.sh b/tests/futility/test_update.sh index aaf46904..c130a56c 100755 --- a/tests/futility/test_update.sh +++ b/tests/futility/test_update.sh @@ -6,16 +6,25 @@ me=${0##*/} TMP="$me.tmp" +# Include /usr/sbin for flahsrom(8) +PATH=/usr/sbin:"${PATH}" + # Test data files LINK_BIOS="${SCRIPTDIR}/data/bios_link_mp.bin" +PEPPY_BIOS="${SCRIPTDIR}/data/bios_peppy_mp.bin" LINK_VERSION="Google_Link.2695.1.133" +PEPPY_VERSION="Google_Peppy.4389.89.0" # Work in scratch directory cd "$OUTDIR" - set -o pipefail -# Test command execution. +# Prepare temporary files. +cp -f "${LINK_BIOS}" "${TMP}.emu" -# The updater is now currently always loading system firmware using flashrom(8) -# and can't be tested until an emulation interface is implemented. +# Test command execution. +versions="$("${FUTILITY}" update -i "${PEPPY_BIOS}" --emulate "${TMP}.emu" | + sed -n 's/.*(//; s/).*//p')" +test "${versions}" = \ +"RO:${PEPPY_VERSION}, RW/A:${PEPPY_VERSION}, RW/B:${PEPPY_VERSION} +RO:${LINK_VERSION}, RW/A:${LINK_VERSION}, RW/B:${LINK_VERSION}" |