summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHung-Te Lin <hungte@chromium.org>2018-08-24 13:06:34 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-08-31 11:19:58 -0700
commit8d8acddf86a76702438aff5f2f8f57df3ff73dd8 (patch)
tree24db30e874bb838648b9282e9867617c0fc44ddc
parentd7d098dfc83c8ae7dd09f07738d22bd8f506a049 (diff)
downloadvboot-8d8acddf86a76702438aff5f2f8f57df3ff73dd8.tar.gz
futility: cmd_update: Implement updater logic "RW UPDATE".
The logic is same as --mode=recovery,--wp=1 in legacy firmware updater. An debugging option '--wp' is introduced so user can easily switch between FULL UPDATE (--wp=0) or RW UPDATE (--wp=1). BUG=chromium:875551 TEST=make futil; futility update -i IMAGE --wp=0; futility update -i IMAGE --wp=1; tests/futility/run_test_scripts.sh $(pwd)/build/futility BRANCH=None Change-Id: Ic7d8aa8b327296988ebf80a8e737e8893b7870ea Signed-off-by: Hung-Te Lin <hungte@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1188016 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--futility/cmd_update.c90
-rwxr-xr-xtests/futility/test_update.sh25
2 files changed, 109 insertions, 6 deletions
diff --git a/futility/cmd_update.c b/futility/cmd_update.c
index c6f70410..97d63aad 100644
--- a/futility/cmd_update.c
+++ b/futility/cmd_update.c
@@ -21,9 +21,13 @@
/* FMAP section names. */
static const char * const FMAP_RO_FRID = "RO_FRID",
+ * const FMAP_RW_SECTION_A = "RW_SECTION_A",
+ * const FMAP_RW_SECTION_B = "RW_SECTION_B",
* const FMAP_RW_FWID = "RW_FWID",
* const FMAP_RW_FWID_A = "RW_FWID_A",
- * const FMAP_RW_FWID_B = "RW_FWID_B";
+ * const FMAP_RW_FWID_B = "RW_FWID_B",
+ * const FMAP_RW_SHARED = "RW_SHARED",
+ * const FMAP_RW_LEGACY = "RW_LEGACY";
/* flashrom programmers. */
static const char * const PROG_HOST = "host",
@@ -31,6 +35,11 @@ static const char * const PROG_HOST = "host",
* const PROG_EC = "ec",
* const PROG_PD = "ec:dev=1";
+enum wp_state {
+ WP_DISABLED,
+ WP_ENABLED,
+};
+
enum flashrom_ops {
FLASHROM_READ,
FLASHROM_WRITE,
@@ -60,8 +69,8 @@ struct system_property {
enum system_property_type {
/* TODO(hungte) Remove SYS_PROP_TEST* when we have more properties. */
SYS_PROP_TEST1,
- SYS_PROP_TEST2,
- SYS_PROP_TEST3,
+ SYS_PROP_WP_HW,
+ SYS_PROP_WP_SW,
SYS_PROP_MAX
};
@@ -72,6 +81,13 @@ struct updater_config {
struct system_property system_properties[SYS_PROP_MAX];
};
+/* A helper function to return the "hardware write protection" status. */
+static int host_get_wp_hw()
+{
+ /* TODO(hungte) Implement this with calling VbGetSystemPropertyInt . */
+ return WP_ENABLED;
+}
+
/*
* A helper function to invoke flashrom(8) command.
* Returns 0 if success, non-zero if error.
@@ -135,6 +151,13 @@ static int host_flashrom(enum flashrom_ops op, const char *image_path,
return r;
}
+/* Helper function to return software write protection switch status. */
+static int host_get_wp_sw()
+{
+ /* TODO(hungte) Implement this with calling flashrom. */
+ return WP_ENABLED;
+}
+
/*
* Gets the system property by given type.
* If the property was not loaded yet, invoke the property getter function
@@ -517,6 +540,19 @@ static int write_optional_firmware(struct updater_config *cfg,
return write_firmware(cfg, image, section_name);
}
+static int is_write_protection_enabled(struct updater_config *cfg)
+{
+ /* Default to enabled. */
+ int wp = get_system_property(SYS_PROP_WP_HW, cfg);
+ if (wp == WP_DISABLED)
+ return wp;
+ /* For error or enabled, check WP SW. */
+ wp = get_system_property(SYS_PROP_WP_SW, cfg);
+ /* Consider all errors as enabled. */
+ if (wp != WP_DISABLED)
+ return WP_ENABLED;
+ return wp;
+}
enum updater_error_codes {
UPDATE_ERR_DONE,
UPDATE_ERR_NO_IMAGE,
@@ -534,6 +570,32 @@ static const char * const updater_error_messages[] = {
};
/*
+ * The main updater for "RW update".
+ * This was also known as --mode=recovery, --wp=1 in legacy updater.
+ * Returns UPDATE_ERR_DONE if success, otherwise error.
+ */
+static enum updater_error_codes update_rw_firmrware(
+ struct updater_config *cfg,
+ struct firmware_image *image_from,
+ struct firmware_image *image_to)
+{
+ printf(">> RW UPDATE: Updating RW sections (%s, %s, and %s).\n",
+ FMAP_RW_SECTION_A, FMAP_RW_SECTION_B, FMAP_RW_SHARED);
+
+ /*
+ * TODO(hungte) Speed up by flashing multiple sections in one
+ * command, or provide diff file.
+ */
+ if (write_firmware(cfg, image_to, FMAP_RW_SECTION_A) ||
+ write_firmware(cfg, image_to, FMAP_RW_SECTION_B) ||
+ write_firmware(cfg, image_to, FMAP_RW_SHARED) ||
+ write_optional_firmware(cfg, image_to, FMAP_RW_LEGACY))
+ return UPDATE_ERR_WRITE_FIRMWARE;
+
+ return UPDATE_ERR_DONE;
+}
+
+/*
* The main updater for "Full update".
* This was also known as "--mode=factory" or "--mode=recovery, --wp=0" in
* legacy updater.
@@ -560,6 +622,7 @@ static enum updater_error_codes update_whole_firmware(
*/
static enum updater_error_codes update_firmware(struct updater_config *cfg)
{
+ int wp_enabled;
struct firmware_image *image_from = &cfg->image_current,
*image_to = &cfg->image;
if (!image_to->data)
@@ -582,10 +645,19 @@ static enum updater_error_codes update_firmware(struct updater_config *cfg)
image_from->file_name, image_from->ro_version,
image_from->rw_version_a, image_from->rw_version_b);
+ wp_enabled = is_write_protection_enabled(cfg);
+ printf(">> Write protection: %d (%s; HW=%d, SW=%d).\n", wp_enabled,
+ wp_enabled ? "enabled" : "disabled",
+ get_system_property(SYS_PROP_WP_HW, cfg),
+ get_system_property(SYS_PROP_WP_SW, cfg));
+
if (debugging_enabled)
print_system_properties(cfg);
- return update_whole_firmware(cfg, image_to);
+ if (wp_enabled)
+ return update_rw_firmrware(cfg, image_from, image_to);
+ else
+ return update_whole_firmware(cfg, image_to);
}
/*
@@ -611,6 +683,7 @@ static struct option const long_opts[] = {
{"image", 1, NULL, 'i'},
{"ec_image", 1, NULL, 'e'},
{"pd_image", 1, NULL, 'P'},
+ {"wp", 1, NULL, 'W'},
{"emulate", 1, NULL, 'E'},
{"sys_props", 1, NULL, 'S'},
{"help", 0, NULL, 'h'},
@@ -629,6 +702,7 @@ static void print_help(int argc, char *argv[])
" --pd_image=FILE \tPD firmware image (i.e, pd.bin)\n"
"\n"
"Debugging and testing options:\n"
+ " --wp=1|0 \tSpecify write protection status\n"
" --emulate=FILE \tEmulate system firmware using file\n"
" --sys_props=LIST\tList of system properties to override\n"
"",
@@ -637,7 +711,7 @@ static void print_help(int argc, char *argv[])
static int do_update(int argc, char *argv[])
{
- int i, errorcnt = 0;
+ int i, r, errorcnt = 0;
struct updater_config cfg = {
.image = { .programmer = PROG_HOST, },
.image_current = { .programmer = PROG_HOST, },
@@ -645,6 +719,8 @@ static int do_update(int argc, char *argv[])
.pd_image = { .programmer = PROG_PD, },
.emulate = 0,
.system_properties = {
+ [SYS_PROP_WP_HW] = {.getter = host_get_wp_hw},
+ [SYS_PROP_WP_SW] = {.getter = host_get_wp_sw},
},
};
@@ -661,6 +737,10 @@ static int do_update(int argc, char *argv[])
break;
case 'P':
errorcnt += load_image(optarg, &cfg.pd_image);
+ case 'W':
+ r = strtol(optarg, NULL, 0);
+ override_system_property(SYS_PROP_WP_HW, &cfg, r);
+ override_system_property(SYS_PROP_WP_SW, &cfg, r);
break;
case 'E':
cfg.emulate = 1;
diff --git a/tests/futility/test_update.sh b/tests/futility/test_update.sh
index ca9c6f85..e06bbc59 100755
--- a/tests/futility/test_update.sh
+++ b/tests/futility/test_update.sh
@@ -33,7 +33,25 @@ FROM_IMAGE=${TMP}.src.peppy
cp -f ${LINK_BIOS} ${TO_IMAGE}
cp -f ${PEPPY_BIOS} ${FROM_IMAGE}
+unpack_image() {
+ local folder="${TMP}.$1"
+ local image="$2"
+ mkdir -p "${folder}"
+ (cd "${folder}" && ${FUTILITY} dump_fmap -x "../${image}")
+}
+
+# Unpack images so we can prepare expected results by individual sections.
+unpack_image "to" "${TO_IMAGE}"
+unpack_image "from" "${FROM_IMAGE}"
+
+# Generate expected results.
cp -f "${TO_IMAGE}" "${TMP}.expected.full"
+cp -f "${FROM_IMAGE}" "${TMP}.expected.rw"
+"${FUTILITY}" load_fmap "${TMP}.expected.rw" \
+ RW_SECTION_A:${TMP}.to/RW_SECTION_A \
+ RW_SECTION_B:${TMP}.to/RW_SECTION_B \
+ RW_SHARED:${TMP}.to/RW_SHARED \
+ RW_LEGACY:${TMP}.to/RW_LEGACY
test_update() {
local test_name="$1"
@@ -52,4 +70,9 @@ test_update() {
# Test Full update.
test_update "Full update" \
"${FROM_IMAGE}" "${TMP}.expected.full" \
- -i "${TO_IMAGE}"
+ -i "${TO_IMAGE}" --wp=0
+
+# Test RW-only update.
+test_update "RW update" \
+ "${FROM_IMAGE}" "${TMP}.expected.rw" \
+ -i "${TO_IMAGE}" --wp=1