summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--futility/cmd_update.c5
-rw-r--r--futility/updater.c36
-rw-r--r--futility/updater.h1
-rwxr-xr-xtests/futility/test_update.sh13
4 files changed, 55 insertions, 0 deletions
diff --git a/futility/cmd_update.c b/futility/cmd_update.c
index 2ba8a4e8..14b16877 100644
--- a/futility/cmd_update.c
+++ b/futility/cmd_update.c
@@ -34,6 +34,7 @@ static struct option const long_opts[] = {
{"programmer", 1, NULL, 'p'},
{"wp", 1, NULL, 'W'},
{"emulate", 1, NULL, 'E'},
+ {"output_dir", 1, NULL, 'U'},
{"sys_props", 1, NULL, 'S'},
{"debug", 0, NULL, 'd'},
{"verbose", 0, NULL, 'v'},
@@ -62,6 +63,7 @@ static void print_help(int argc, char *argv[])
"-m, --mode=MODE \tRun updater in given mode\n"
" --factory \tAlias for --mode=factory\n"
" --force \tForce update (skip checking contents)\n"
+ " --output_dir=DIR\tSpecify the target for --mode=output\n"
"\n"
"Debugging and testing options:\n"
" --wp=1|0 \tSpecify write protection status\n"
@@ -112,6 +114,9 @@ static int do_update(int argc, char *argv[])
case 'm':
args.mode = optarg;
break;
+ case 'U':
+ args.output_dir = optarg;
+ break;
case 'M':
args.model = optarg;
break;
diff --git a/futility/updater.c b/futility/updater.c
index 0d69641b..6029612d 100644
--- a/futility/updater.c
+++ b/futility/updater.c
@@ -1668,6 +1668,30 @@ static int updater_load_images(struct updater_config *cfg,
}
/*
+ * Writes a firmware image to specified file.
+ * Returns 0 on success, otherwise failure.
+ */
+static int updater_output_image(const struct firmware_image *image,
+ const char *fname, const char *root)
+{
+ int r = 0;
+ char *fpath;
+
+ if (!image->data)
+ return 0;
+
+ ASPRINTF(&fpath, "%s/%s", root, fname);
+ r = vb2_write_file(fpath, image->data, image->size);
+ if (r)
+ ERROR("Failed writing firmware image to: %s", fpath);
+ else
+ printf("Firmware image saved in: %s\n", fpath);
+
+ free(fpath);
+ return !!r;
+}
+
+/*
* Applies white label information to an existing model config.
* Returns 0 on success, otherwise failure.
*/
@@ -1760,6 +1784,7 @@ int updater_setup_config(struct updater_config *cfg,
{
int errorcnt = 0;
int check_single_image = 0, check_wp_disabled = 0;
+ int do_output = 0;
const char *default_quirks = NULL;
const char *archive_path = arg->archive;
@@ -1796,6 +1821,8 @@ int updater_setup_config(struct updater_config *cfg,
} else if (strcmp(arg->mode, "factory") == 0 ||
strcmp(arg->mode, "factory_install") == 0) {
cfg->factory_update = 1;
+ } else if (strcmp(arg->mode, "output") == 0) {
+ do_output = 1;
} else {
errorcnt++;
ERROR("Invalid mode: %s", arg->mode);
@@ -1892,6 +1919,15 @@ int updater_setup_config(struct updater_config *cfg,
errorcnt++;
ERROR("Factory mode needs WP disabled.");
}
+ if (!errorcnt && do_output) {
+ const char *r = arg->output_dir;
+ if (!r)
+ r = ".";
+ errorcnt += updater_output_image(&cfg->image, "bios.bin", r);
+ errorcnt += updater_output_image(&cfg->ec_image, "ec.bin", r);
+ errorcnt += updater_output_image(&cfg->pd_image, "pd.bin", r);
+ *do_update = 0;
+ }
return errorcnt;
}
diff --git a/futility/updater.h b/futility/updater.h
index ae6db16a..26e88dad 100644
--- a/futility/updater.h
+++ b/futility/updater.h
@@ -116,6 +116,7 @@ struct updater_config_arguments {
char *archive, *quirks, *mode;
char *programmer, *model, *signature_id;
char *emulation, *sys_props, *write_protection;
+ char *output_dir;
int is_factory, try_update, force_update, do_manifest;
int verbosity;
};
diff --git a/tests/futility/test_update.sh b/tests/futility/test_update.sh
index 215f9918..3838361c 100755
--- a/tests/futility/test_update.sh
+++ b/tests/futility/test_update.sh
@@ -310,6 +310,11 @@ test_update "Full update (--archive, single package)" \
"${FROM_IMAGE}" "${TMP}.expected.full" \
-a "${A}" --wp=0 --sys_props 0,0x10001,1,3
+echo "TEST: Output (--mode=output)"
+mkdir -p "${TMP}.output"
+${FUTILITY} update -i "${LINK_BIOS}" --mode=output --output_dir="${TMP}.output"
+cmp "${LINK_BIOS}" "${TMP}.output/bios.bin"
+
mkdir -p "${A}/keyset"
cp -f "${LINK_BIOS}" "${A}/bios.bin"
cp -f "${TMP}.to/rootkey" "${A}/keyset/rootkey.WL"
@@ -336,6 +341,14 @@ WL_TAG="WL" PATH="${A}/bin:${PATH}" \
"${A}/bios.bin" "${LINK_BIOS}" \
-a "${A}" --wp=0 --sys_props 0,0x10001,1,3
+echo "TEST: Output (-a, --mode=output)"
+mkdir -p "${TMP}.outa"
+cp -f "${A}/bios.bin" "${TMP}.emu"
+WL_TAG="WL" PATH="${A}/bin:${PATH}" \
+ ${FUTILITY} update -a "${A}" --mode=output --emu="${TMP}.emu" \
+ --output_dir="${TMP}.outa"
+cmp "${LINK_BIOS}" "${TMP}.outa/bios.bin"
+
# Test archive with Unified Build contents.
cp -r "${SCRIPTDIR}/models" "${A}/"
mkdir -p "${A}/images"