diff options
-rw-r--r-- | futility/cmd_update.c | 26 | ||||
-rw-r--r-- | futility/updater.c | 16 | ||||
-rw-r--r-- | futility/updater.h | 4 | ||||
-rwxr-xr-x | tests/futility/test_update.sh | 8 |
4 files changed, 47 insertions, 7 deletions
diff --git a/futility/cmd_update.c b/futility/cmd_update.c index db29db20..3d99664e 100644 --- a/futility/cmd_update.c +++ b/futility/cmd_update.c @@ -21,6 +21,7 @@ enum { OPT_FACTORY, OPT_FAST, OPT_FORCE, + OPT_GBB_FLAGS, OPT_HOST_ONLY, OPT_MANIFEST, OPT_MODEL, @@ -58,6 +59,7 @@ static struct option const long_opts[] = { {"factory", 0, NULL, OPT_FACTORY}, {"fast", 0, NULL, OPT_FAST}, {"force", 0, NULL, OPT_FORCE}, + {"gbb_flags", 1, NULL, OPT_GBB_FLAGS}, {"host_only", 0, NULL, OPT_HOST_ONLY}, {"list-quirks", 0, NULL, OPT_QUIRKS_LIST}, {"manifest", 0, NULL, OPT_MANIFEST}, @@ -90,6 +92,17 @@ static void print_help(int argc, char *argv[]) printf("\n" "Usage: " MYNAME " %s [OPTIONS]\n" "\n" + "Updates firmware in one of the following modes (default to recovery):\n" + " autoupdate:\tUpdate RW[A|B], or recovery if RO changed.\n" + " recovery: \tUpdate RW[A&B], (RO, RO:GBB[keys] - if RO changed)\n" + " factory: \tUpdate RW[A&B], RO, RO:GBB[keys,flags]\n" + "\n" + "Note: firmware sections with PRESERVE flags like VPD and\n" + " HWID in GBB are always preserved.\n" + " GBB flags are preserved in autoupdate and recovery modes.\n" + "\n" + "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" @@ -102,9 +115,9 @@ static void print_help(int argc, char *argv[]) " --fast \tReduce read cycles and do not verify\n" " --quirks=LIST \tSpecify the quirks to apply\n" " --list-quirks \tPrint all available quirks\n" + "-m, --mode=MODE \tRun updater in specified mode\n" "\n" "Legacy and compatibility options:\n" - "-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" @@ -114,6 +127,7 @@ static void print_help(int argc, char *argv[]) " --host_only \tUpdate only AP (host) firmware\n" " --emulate=FILE \tEmulate system firmware using file\n" " --model=MODEL \tOverride system model for images\n" + " --gbb_flags=FLAG\tOverride new GBB flags\n" " --ccd \tDo fast,force,wp=0,p=raiden_debug_spi\n" " --servo \tFlash using Servo (v2, v4, micro, ...)\n" " --servo_port=PRT\tOverride servod port, implies --servo\n" @@ -132,6 +146,7 @@ static int do_update(int argc, char *argv[]) int i, errorcnt = 0, do_update = 1; int detect_servo = 0, do_servo_cpu_fw_spi = 0; char *servo_programmer = NULL; + char *endptr; cfg = updater_new_config(); assert(cfg); @@ -218,6 +233,15 @@ static int do_update(int argc, char *argv[]) case OPT_FAST: args.fast_update = 1; break; + case OPT_GBB_FLAGS: + args.gbb_flags = strtoul(optarg, &endptr, 0); + if (*endptr) { + ERROR("Invalid flags: %s\n", optarg); + errorcnt++; + } else { + args.override_gbb_flags = 1; + } + break; case OPT_CCD: args.fast_update = 1; args.force_update = 1; diff --git a/futility/updater.c b/futility/updater.c index a8dfb8d8..8048a5b7 100644 --- a/futility/updater.c +++ b/futility/updater.c @@ -472,7 +472,8 @@ static int write_optional_firmware(struct updater_config *cfg, */ static int preserve_gbb(const struct firmware_image *image_from, struct firmware_image *image_to, - int preserve_flags) + int preserve_flags, int override_flags, + uint64_t override_value) { const struct vb2_gbb_header *gbb_from; struct vb2_gbb_header *gbb_to; @@ -484,8 +485,10 @@ static int preserve_gbb(const struct firmware_image *image_from, if (!gbb_from || !gbb_to) return -1; - /* Preserve flags (for non-factory mode). */ - if (preserve_flags) + /* Preserve (for non-factory mode) or override flags. */ + if (override_flags) + gbb_to->flags = override_value; + else if (preserve_flags) gbb_to->flags = gbb_from->flags; /* Preserve HWID. */ @@ -583,7 +586,8 @@ static int preserve_images(struct updater_config *cfg) int errcnt = 0, found; struct firmware_image *from = &cfg->image_current, *to = &cfg->image; - errcnt += preserve_gbb(from, to, !cfg->factory_update); + errcnt += preserve_gbb(from, to, !cfg->factory_update, + cfg->override_gbb_flags, cfg->gbb_flags); errcnt += preserve_management_engine(cfg, from, to); errcnt += preserve_fmap_sections(from, to, &found); @@ -998,7 +1002,7 @@ static enum updater_error_codes update_try_rw_firmware( int has_update = 1; int is_vboot2 = get_system_property(SYS_PROP_FW_VBOOT2, cfg); - preserve_gbb(image_from, image_to, 1); + preserve_gbb(image_from, image_to, 1, 0, 0); if (!wp_enabled && section_needs_update( image_from, image_to, FMAP_RO_SECTION)) return UPDATE_ERR_NEED_RO_UPDATE; @@ -1502,6 +1506,8 @@ int updater_setup_config(struct updater_config *cfg, check_wp_disabled = 1; cfg->try_update = 0; } + cfg->gbb_flags = arg->gbb_flags; + cfg->override_gbb_flags = arg->override_gbb_flags; /* Setup properties and fields that do not have external dependency. */ if (arg->programmer) { diff --git a/futility/updater.h b/futility/updater.h index e11cc745..57829cbe 100644 --- a/futility/updater.h +++ b/futility/updater.h @@ -69,6 +69,8 @@ struct updater_config { int fast_update; int verbosity; const char *emulation; + int override_gbb_flags; + uint32_t gbb_flags; }; struct updater_config_arguments { @@ -82,6 +84,8 @@ struct updater_config_arguments { int is_factory, try_update, force_update, do_manifest, host_only; int fast_update; int verbosity; + int override_gbb_flags; + uint32_t gbb_flags; }; struct patch_config { diff --git a/tests/futility/test_update.sh b/tests/futility/test_update.sh index 002f1050..57b3f460 100755 --- a/tests/futility/test_update.sh +++ b/tests/futility/test_update.sh @@ -133,6 +133,8 @@ cp -f "${TMP}.expected.full" "${TMP}.expected.full.gbb0" "${FUTILITY}" gbb -s --flags=0 "${TMP}.expected.full.gbb0" cp -f "${FROM_IMAGE}" "${FROM_IMAGE}.gbb0" "${FUTILITY}" gbb -s --flags=0 "${FROM_IMAGE}.gbb0" +cp -f "${TMP}.expected.full" "${TMP}.expected.full.gbb0x27" +"${FUTILITY}" gbb -s --flags=0x27 "${TMP}.expected.full.gbb0x27" cp -f "${TMP}.expected.full" "${TMP}.expected.large" dd if=/dev/zero bs=8388608 count=1 | tr '\000' '\377' >>"${TMP}.expected.large" cp -f "${TMP}.expected.full" "${TMP}.expected.me_unlocked" @@ -209,6 +211,10 @@ test_update "Full update (GBB=0 -> 0)" \ "${FROM_IMAGE}.gbb0" "${TMP}.expected.full.gbb0" \ -i "${TO_IMAGE}" --wp=0 --sys_props 0,0x10001,1 +test_update "Full update (GBB flags -> 0x27)" \ + "${FROM_IMAGE}" "${TMP}.expected.full.gbb0x27" \ + -i "${TO_IMAGE}" --gbb_flags=0x27 --wp=0 --sys_props 0,0x10001,1 + test_update "Full update (--host_only)" \ "${FROM_IMAGE}" "${TMP}.expected.full" \ -i "${TO_IMAGE}" --wp=0 --sys_props 0,0x10001,1 \ @@ -302,7 +308,7 @@ test_update "Factory mode update (WP=1)" \ "${FROM_IMAGE}" "!remove write protection for factory mode" \ --factory -i "${TO_IMAGE}" --wp=1 --sys_props 0,0x10001,1 -test_update "Factory mode update (GBB=0 -> 39)" \ +test_update "Factory mode update (GBB=0 -> 0x39)" \ "${FROM_IMAGE}.gbb0" "${TMP}.expected.full" \ --factory -i "${TO_IMAGE}" --wp=0 --sys_props 0,0x10001,1 |