summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHung-Te Lin <hungte@chromium.org>2018-08-21 17:49:06 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-08-31 05:22:45 -0700
commit6de8d9a5b1a84a7ed93eda6bdb11dcd4995d110a (patch)
tree7098532ded27f61421f9b615650022563ab42cfd
parentd5e8445e3fd4694802e2246dd7e4c0df55ef0adc (diff)
downloadvboot-6de8d9a5b1a84a7ed93eda6bdb11dcd4995d110a.tar.gz
futility: cmd_update: Support loading image files by -i, -e, --pd_image
To specify images, we want to read them from files specified from command line: -i: AP (host) firmware image. -e: EC firmware image. --pd_image: PD firmware image (deprecated). BUG=chromium:875551 TEST=make futil; futility update -i /build/eve/firmware/image.bin tests/futility/run_test_script.sh $(pwd)/build/futility BRANCH=None Change-Id: I3c2dbe3d3ce4619aa7e044a154be3aba7ab9181c Signed-off-by: Hung-Te Lin <hungte@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1183648 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--futility/cmd_update.c88
-rwxr-xr-xtests/futility/test_update.sh6
2 files changed, 92 insertions, 2 deletions
diff --git a/futility/cmd_update.c b/futility/cmd_update.c
index ac1246e4..7061292c 100644
--- a/futility/cmd_update.c
+++ b/futility/cmd_update.c
@@ -6,16 +6,67 @@
* A reference implementation for AP (and supporting images) firmware updater.
*/
+#include <assert.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include "futility.h"
+#include "host_misc.h"
#include "utility.h"
+/* flashrom programmers. */
+static const char * const PROG_HOST = "host",
+ * const PROG_EC = "ec",
+ * const PROG_PD = "ec:dev=1";
+
+struct firmware_image {
+ const char *programmer;
+ uint32_t size;
+ uint8_t *data;
+ char *file_name;
+ char *ro_version, *rw_version_a, *rw_version_b;
+};
+
struct updater_config {
+ struct firmware_image image, image_current;
+ struct firmware_image ec_image, pd_image;
};
+/*
+ * Loads a firmware image from file.
+ * Returns 0 on success, otherwise failure.
+ */
+static int load_image(const char *file_name, struct firmware_image *image)
+{
+ Debug("%s: Load image file from %s...\n", __FUNCTION__, file_name);
+
+ if (vb2_read_file(file_name, &image->data, &image->size) != VB2_SUCCESS)
+ {
+ Error("%s: Failed to load %s\n", __FUNCTION__, file_name);
+ return -1;
+ }
+
+ Debug("%s: Image size: %d\n", __FUNCTION__, image->size);
+ assert(image->data);
+ image->file_name = strdup(file_name);
+
+ return 0;
+}
+
+/*
+ * Frees the allocated resource from a firmware image object.
+ */
+static void free_image(struct firmware_image *image)
+{
+ free(image->data);
+ free(image->file_name);
+ free(image->ro_version);
+ free(image->rw_version_a);
+ free(image->rw_version_b);
+ memset(image, 0, sizeof(*image));
+}
+
enum updater_error_codes {
UPDATE_ERR_DONE,
UPDATE_ERR_UNKNOWN,
@@ -35,20 +86,37 @@ static enum updater_error_codes update_firmware(struct updater_config *cfg)
return UPDATE_ERR_DONE;
}
+/*
+ * Releases all loaded images in an updater configuration object.
+ */
+static void unload_updater_config(struct updater_config *cfg)
+{
+ free_image(&cfg->image);
+ free_image(&cfg->image_current);
+ free_image(&cfg->ec_image);
+ free_image(&cfg->pd_image);
+}
+
/* Command line options */
static struct option const long_opts[] = {
/* name has_arg *flag val */
+ {"image", 1, NULL, 'i'},
+ {"ec_image", 1, NULL, 'e'},
+ {"pd_image", 1, NULL, 'P'},
{"help", 0, NULL, 'h'},
{NULL, 0, NULL, 0},
};
-static const char * const short_opts = "h";
+static const char * const short_opts = "hi:e:";
static void print_help(int argc, char *argv[])
{
printf("\n"
"Usage: " MYNAME " %s [OPTIONS]\n"
"\n"
+ "-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"
"",
argv[0]);
}
@@ -56,13 +124,28 @@ static void print_help(int argc, char *argv[])
static int do_update(int argc, char *argv[])
{
int i, errorcnt = 0;
- struct updater_config cfg = {};
+ struct updater_config cfg = {
+ .image = { .programmer = PROG_HOST, },
+ .image_current = { .programmer = PROG_HOST, },
+ .ec_image = { .programmer = PROG_EC, },
+ .pd_image = { .programmer = PROG_PD, },
+ };
printf(">> Firmware updater started.\n");
opterr = 0;
while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) {
switch (i) {
+ case 'i':
+ errorcnt += load_image(optarg, &cfg.image);
+ break;
+ case 'e':
+ errorcnt += load_image(optarg, &cfg.ec_image);
+ break;
+ case 'P':
+ errorcnt += load_image(optarg, &cfg.pd_image);
+ break;
+
case 'h':
print_help(argc, argv);
return !!errorcnt;
@@ -97,6 +180,7 @@ static int do_update(int argc, char *argv[])
errorcnt ? "FAILED": "DONE",
errorcnt ? "stopped due to error" : "exited successfully");
+ unload_updater_config(&cfg);
return !!errorcnt;
}
diff --git a/tests/futility/test_update.sh b/tests/futility/test_update.sh
index 7f747c61..6aa12ceb 100755
--- a/tests/futility/test_update.sh
+++ b/tests/futility/test_update.sh
@@ -6,8 +6,14 @@
me=${0##*/}
TMP="$me.tmp"
+# Test data files
+LINK_BIOS="${SCRIPTDIR}/data/bios_link_mp.bin"
+
# Work in scratch directory
cd "$OUTDIR"
+set -o pipefail
+
# Test command execution.
"${FUTILITY}" update
+"${FUTILITY}" --debug update -i "${LINK_BIOS}" | grep 8388608