From ff29ee63ed52b698afcaa4c2619d7163322a3785 Mon Sep 17 00:00:00 2001 From: Sam McNally Date: Tue, 18 Oct 2022 20:38:52 +1100 Subject: futility: updater: Detect the model via FRID for non-host programmers When updating with --archive and a non-host programmer (and thus no reliable crosid to discover the appropriate firmware manifest key), and no explicit --model parameter is passed, try to detect the model by matching the FRID of the current firmware with one of the host firmware images in the archive. Add a --detect-model-only flag to perform the same matching, but report the detected model name and exit. This can be used in combination with the manifest to automatically select an appropriate EC image to pass to flash_ec. BUG=b:253966060 TEST=futility update -a firmware.tar.bz2 --servo BRANCH=None Signed-off-by: Sam McNally Change-Id: I25fa0f109d0d8052179b220251d4720438b93bc4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3965584 Reviewed-by: Edward O'Callaghan Reviewed-by: Yu-Ping Wu --- futility/updater_manifest.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'futility/updater_manifest.c') diff --git a/futility/updater_manifest.c b/futility/updater_manifest.c index 339bfd8a..ca338c40 100644 --- a/futility/updater_manifest.c +++ b/futility/updater_manifest.c @@ -706,6 +706,58 @@ const struct model_config *manifest_find_model(const struct manifest *manifest, return model; } +const struct model_config * +manifest_detect_model_from_frid(struct updater_config *cfg, + struct manifest *manifest) +{ + const struct model_config *result = NULL; + struct firmware_image current_ro_frid = {0}; + current_ro_frid.programmer = cfg->image_current.programmer; + int error = flashrom_read_region(¤t_ro_frid, FMAP_RO_FRID, + cfg->verbosity + 1); + const char *from_dot; + int len; + + if (error) + return NULL; + + current_ro_frid.data[current_ro_frid.size - 1] = '\0'; + from_dot = strchr((const char *)current_ro_frid.data, '.'); + if (!from_dot) { + VB2_DEBUG("Missing dot (%s)\n", + (const char *)current_ro_frid.data); + goto cleanup; + } + len = from_dot - (const char *)current_ro_frid.data + 1; + + for (int i = 0; i < manifest->num && !result; ++i) { + struct model_config *m = &manifest->models[i]; + struct firmware_image image = {0}; + + if (load_firmware_image(&image, m->image, manifest->archive)) + return NULL; + + VB2_DEBUG("Comparing '%*.*s' with '%*.*s'\n", len, len, + (const char *)current_ro_frid.data, len, len, + image.ro_version); + if (strncasecmp((const char *)current_ro_frid.data, + image.ro_version, len) == 0) { + result = m; + } + free_firmware_image(&image); + } + if (result) { + INFO("Detected model: '%s'\n", result->name); + } else { + ERROR("Unsupported FRID: '%*.*s'.\n", len - 1, len - 1, + (const char *)current_ro_frid.data); + } +cleanup: + free_firmware_image(¤t_ro_frid); + + return result; +} + /* * Determines the signature ID to use for custom label. * Returns the signature ID for looking up rootkey and vblock files. -- cgit v1.2.1