diff options
author | Hung-Te Lin <hungte@chromium.org> | 2018-08-24 13:06:34 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-08-31 11:19:58 -0700 |
commit | 8d8acddf86a76702438aff5f2f8f57df3ff73dd8 (patch) | |
tree | 24db30e874bb838648b9282e9867617c0fc44ddc | |
parent | d7d098dfc83c8ae7dd09f07738d22bd8f506a049 (diff) | |
download | vboot-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.c | 90 | ||||
-rwxr-xr-x | tests/futility/test_update.sh | 25 |
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 |