diff options
author | Edward O'Callaghan <quasisec@google.com> | 2021-10-28 10:53:18 +1100 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-11-18 23:04:40 +0000 |
commit | 483dff64346fd30224df5b66bf76124aeea7bb12 (patch) | |
tree | 75bbc6a98a66fcb0a5e7a688237496675a89c2e1 /futility | |
parent | 4200cb21c7f6c79dacee511400c88994bca5cf7f (diff) | |
download | vboot-483dff64346fd30224df5b66bf76124aeea7bb12.tar.gz |
vboot_reference/futility: Port W path to using libflashrom
Use libflashrom API over sub-processing the flashrom CLI.
Squash in,
vboot_reference/futility: Use image layout as fallback
Use the layout encoding within the image as the fallback if
we cannot read it from ROM. Also cleanup error paths while
here.
BUG=b:203715651
BRANCH=none
TEST=cros deploy to nocturne and ran:
`/usr/sbin/chromeos-firmwareupdate --mode=recovery --wp=1`.
&& `$ cros_run_unit_tests --board nocturne --packages vboot_reference`.
Cq-Depend: chromium:3249690, chromium:3281062, chromium:3288610
Signed-off-by: Edward O'Callaghan <quasisec@google.com>
Change-Id: I892aec510d8023abd42a07cbb036be79bc8b4498
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3247852
Tested-by: Edward O'Callaghan <quasisec@chromium.org>
Auto-Submit: Edward O'Callaghan <quasisec@chromium.org>
Commit-Queue: Edward O'Callaghan <quasisec@chromium.org>
Reviewed-by: Sam McNally <sammc@chromium.org>
Diffstat (limited to 'futility')
-rw-r--r-- | futility/updater_utils.c | 147 |
1 files changed, 118 insertions, 29 deletions
diff --git a/futility/updater_utils.c b/futility/updater_utils.c index 51936a52..039788a2 100644 --- a/futility/updater_utils.c +++ b/futility/updater_utils.c @@ -9,11 +9,14 @@ #include <limits.h> #include <sys/stat.h> #include <sys/types.h> +#include <string.h> #include <unistd.h> #if defined (__FreeBSD__) || defined(__OpenBSD__) #include <sys/wait.h> #endif +#include <libflashrom.h> + #include "2common.h" #include "crossystem.h" #include "host_misc.h" @@ -25,7 +28,6 @@ enum flashrom_ops { FLASHROM_READ, - FLASHROM_WRITE, FLASHROM_WP_STATUS, }; @@ -565,11 +567,6 @@ static int host_flashrom(enum flashrom_ops op, const char *image_path, assert(image_path); break; - case FLASHROM_WRITE: - op_cmd = "-w"; - assert(image_path); - break; - case FLASHROM_WP_STATUS: op_cmd = "--wp-status"; assert(image_path == NULL); @@ -587,7 +584,7 @@ static int host_flashrom(enum flashrom_ops op, const char *image_path, if (!extra) extra = ""; - /* TODO(hungte) In future we should link with flashrom directly. */ + /* TODO(b/203715651): link with flashrom directly. */ ASPRINTF(&command, "flashrom %s %s -p %s %s %s %s %s", op_cmd, image_path, programmer, dash_i, section_name, extra, postfix); @@ -618,6 +615,119 @@ static int host_flashrom(enum flashrom_ops op, const char *image_path, return r; } +static int flashrom_print_cb(enum flashrom_log_level level, const char *fmt, + va_list ap) +{ + int ret = 0; + enum flashrom_log_level verbose_screen = FLASHROM_MSG_INFO; + FILE *output_type = (level < verbose_screen) ? stderr : stdout; + + if (level > verbose_screen) + return ret; + +#define COLOUR_RESET "\033[0;m" +#define MAGENTA_TEXT "\033[35;1m" + + if (level != FLASHROM_MSG_SPEW) + fprintf(output_type, MAGENTA_TEXT); + + ret = vfprintf(output_type, fmt, ap); + /* msg_*spew often happens inside chip accessors + * in possibly time-critical operations. + * Don't slow them down by flushing. + */ + if (level != FLASHROM_MSG_SPEW) { + fprintf(output_type, COLOUR_RESET); + fflush(output_type); + } + + return ret; +} + +static char *flashrom_extract_params(const char *str, char **prog, char **params) +{ + char *tmp = strdup(str); + *prog = strtok(tmp, ":"); + *params = strtok(NULL, ""); + return tmp; +} + +static int host_flashrom_write(const struct firmware_image *image, + const char *region, + const struct firmware_image *diff_image) +{ + int r = 0; + size_t len = 0; + + char *programmer, *params; + char *tmp = flashrom_extract_params(image->programmer, &programmer, ¶ms); + + struct flashrom_programmer *prog = NULL; + struct flashrom_flashctx *flashctx = NULL; + struct flashrom_layout *layout = NULL; + + flashrom_set_log_callback((flashrom_log_callback *)&flashrom_print_cb); + + r |= flashrom_init(1); + r |= flashrom_programmer_init(&prog, programmer, params); + r |= flashrom_flash_probe(&flashctx, prog, NULL); + + len = flashrom_flash_getsize(flashctx); + if (len == 0) { + ERROR("zero sized flash detected\n"); + r = -1; + goto err_cleanup; + } + + if (diff_image) { + if (diff_image->size != image->size) { + ERROR("diff_image->size != image->size"); + r = -1; + goto err_cleanup; + } + } + + if (region) { + r = flashrom_layout_read_fmap_from_buffer( + &layout, flashctx, (const uint8_t *)image->data, + image->size); + if (r > 0) { + WARN("could not read fmap from image, r=%d, " + "falling back to read from rom\n", r); + r = flashrom_layout_read_fmap_from_rom( + &layout, flashctx, 0, len); + if (r > 0) { + ERROR("could not read fmap from rom, r=%d\n", r); + r = -1; + goto err_cleanup; + } + } + // empty region causes seg fault in API. + r |= flashrom_layout_include_region(layout, region); + if (r > 0) { + ERROR("could not include region = '%s'\n", region); + r = -1; + goto err_cleanup; + } + } + + flashrom_flag_set(flashctx, FLASHROM_FLAG_VERIFY_WHOLE_CHIP, true); + flashrom_flag_set(flashctx, FLASHROM_FLAG_VERIFY_AFTER_WRITE, true); + if (diff_image) /* equiv --noverify --flash-contents=diff_image at cli */ + flashrom_flag_set(flashctx, FLASHROM_FLAG_VERIFY_AFTER_WRITE, false); + + r |= flashrom_image_write(flashctx, image->data, image->size, + diff_image ? diff_image->data : NULL); + +err_cleanup: + r |= flashrom_programmer_shutdown(prog); + flashrom_layout_release(layout); + flashrom_flash_release(flashctx); + free(tmp); + + return r; +} + /* Helper function to return write protection status via given programmer. */ enum wp_state host_get_wp(const char *programmer) { @@ -673,28 +783,7 @@ int write_system_firmware(const struct firmware_image *image, struct tempfile *tempfiles, int verbosity) { - const char *tmp_path = get_firmware_image_temp_file(image, tempfiles); - const char *tmp_diff = NULL; - - const char *programmer = image->programmer; - char *extra = NULL; - int r; - - if (!tmp_path) - return -1; - - if (diff_image) { - tmp_diff = get_firmware_image_temp_file( - diff_image, tempfiles); - if (!tmp_diff) - return -1; - ASPRINTF(&extra, "--noverify --flash-contents=%s", tmp_diff); - } - - r = host_flashrom(FLASHROM_WRITE, tmp_path, programmer, verbosity, - section_name, extra); - free(extra); - return r; + return host_flashrom_write(image, section_name, diff_image); } /* Helper function to configure all properties. */ |