summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward O'Callaghan <quasisec@google.com>2021-12-21 11:03:53 +1100
committerCommit Bot <commit-bot@chromium.org>2021-12-24 00:50:51 +0000
commitb9859822af4a709e344607fce987a6ef2a75ac75 (patch)
tree4005d4f5a8513164736c402ded1f4e0894334674
parentf2c41528b1324c9c546e0b59b73bfe6e3b98e7b7 (diff)
downloadvboot-b9859822af4a709e344607fce987a6ef2a75ac75.tar.gz
vboot_ref/futility: Extract out flashrom call logic
Separate out all the flashrom worker code used in futility to allow for later building a futility without flashrom support. BUG=b:203715651,b:209702505 BRANCH=none TEST=builds Signed-off-by: Edward O'Callaghan <quasisec@google.com> Change-Id: I938141056424f8f93a598bbb288ee7c8770edc95 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3350298 Tested-by: Edward O'Callaghan <quasisec@chromium.org> Auto-Submit: Edward O'Callaghan <quasisec@chromium.org> Reviewed-by: Hung-Te Lin <hungte@chromium.org> Commit-Queue: Edward O'Callaghan <quasisec@chromium.org>
-rw-r--r--Makefile3
-rw-r--r--futility/flashrom_drv.c197
-rw-r--r--futility/updater.c2
-rw-r--r--futility/updater_utils.c197
-rw-r--r--futility/updater_utils.h8
5 files changed, 216 insertions, 191 deletions
diff --git a/Makefile b/Makefile
index 25539c73..8fc602ed 100644
--- a/Makefile
+++ b/Makefile
@@ -665,7 +665,8 @@ FUTIL_SRCS = \
futility/updater_quirks.c \
futility/updater_utils.c \
futility/vb1_helper.c \
- futility/vb2_helper.c
+ futility/vb2_helper.c \
+ futility/flashrom_drv.c
# List of commands built in futility.
FUTIL_CMD_LIST = ${BUILD}/gen/futility_cmds.c
diff --git a/futility/flashrom_drv.c b/futility/flashrom_drv.c
new file mode 100644
index 00000000..5ebe4468
--- /dev/null
+++ b/futility/flashrom_drv.c
@@ -0,0 +1,197 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * The utility functions for firmware updater.
+ */
+
+#include <libflashrom.h>
+
+#include "2common.h"
+#include "crossystem.h"
+#include "host_misc.h"
+#include "util_misc.h"
+#include "updater.h"
+
+#define FLASHROM_OUTPUT_WP_PATTERN "write protect is "
+
+/* System environment values. */
+static const char * const FLASHROM_OUTPUT_WP_ENABLED =
+ FLASHROM_OUTPUT_WP_PATTERN "enabled",
+ * const FLASHROM_OUTPUT_WP_DISABLED =
+ FLASHROM_OUTPUT_WP_PATTERN "disabled";
+
+// global to allow verbosity level to be injected into callback.
+static enum flashrom_log_level g_verbose_screen = FLASHROM_MSG_INFO;
+
+static int flashrom_print_cb(enum flashrom_log_level level, const char *fmt,
+ va_list ap)
+{
+ int ret = 0;
+ FILE *output_type = (level < FLASHROM_MSG_INFO) ? stderr : stdout;
+
+ if (level > g_verbose_screen)
+ return ret;
+
+ 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)
+ 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;
+}
+
+int flashrom_read_image(struct firmware_image *image, int verbosity)
+{
+ int r = 0;
+ size_t len = 0;
+
+ g_verbose_screen = verbosity;
+
+ char *programmer, *params;
+ char *tmp = flashrom_extract_params(image->programmer, &programmer, &params);
+
+ struct flashrom_programmer *prog = NULL;
+ struct flashrom_flashctx *flashctx = 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);
+ image->data = calloc(1, len);
+ image->size = len;
+ image->file_name = strdup("<none>");
+
+ r |= flashrom_image_read(flashctx, image->data, len);
+
+ r |= flashrom_programmer_shutdown(prog);
+ flashrom_flash_release(flashctx);
+ free(tmp);
+
+ return r;
+}
+
+int flashrom_write_image(const struct firmware_image *image,
+ const char *region,
+ const struct firmware_image *diff_image,
+ int verbosity)
+{
+ int r = 0;
+ size_t len = 0;
+
+ g_verbose_screen = verbosity;
+
+ char *programmer, *params;
+ char *tmp = flashrom_extract_params(image->programmer, &programmer, &params);
+
+ 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_layout_set(flashctx, layout);
+ }
+
+ 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 flashrom_get_wp(const char *programmer)
+{
+ char *command, *result;
+ const char *postfix;
+ int r;
+
+ /* grep is needed because host_shell only returns 1 line. */
+ postfix = " 2>/dev/null | grep \"" FLASHROM_OUTPUT_WP_PATTERN "\"";
+
+
+ /* TODO(b/203715651): link with flashrom directly. */
+ ASPRINTF(&command, "flashrom --wp-status -p %s %s", programmer, postfix);
+
+ /* invokes flashrom(8) with non-zero result if error. */
+ result = host_shell(command);
+ strip_string(result, NULL);
+ free(command);
+ VB2_DEBUG("wp-status: %s\n", result);
+
+ if (strstr(result, FLASHROM_OUTPUT_WP_ENABLED))
+ r = WP_ENABLED;
+ else if (strstr(result, FLASHROM_OUTPUT_WP_DISABLED))
+ r = WP_DISABLED;
+ else
+ r = WP_ERROR;
+ free(result);
+
+ return r;
+}
diff --git a/futility/updater.c b/futility/updater.c
index 8b1c1555..b550b33c 100644
--- a/futility/updater.c
+++ b/futility/updater.c
@@ -458,7 +458,7 @@ static int write_optional_firmware(struct updater_config *cfg,
*/
if (check_programmer_wp &&
get_system_property(SYS_PROP_WP_HW, cfg) == WP_ENABLED &&
- host_get_wp(image->programmer) == WP_ENABLED) {
+ flashrom_get_wp(image->programmer) == WP_ENABLED) {
ERROR("Target %s is write protected, skip updating.\n",
image->programmer);
return 0;
diff --git a/futility/updater_utils.c b/futility/updater_utils.c
index 503747ac..936abaf3 100644
--- a/futility/updater_utils.c
+++ b/futility/updater_utils.c
@@ -15,8 +15,6 @@
#include <sys/wait.h>
#endif
-#include <libflashrom.h>
-
#include "2common.h"
#include "crossystem.h"
#include "host_misc.h"
@@ -24,14 +22,9 @@
#include "updater.h"
#define COMMAND_BUFFER_SIZE 256
-#define FLASHROM_OUTPUT_WP_PATTERN "write protect is "
/* System environment values. */
-static const char * const STR_REV = "rev",
- * const FLASHROM_OUTPUT_WP_ENABLED =
- FLASHROM_OUTPUT_WP_PATTERN "enabled",
- * const FLASHROM_OUTPUT_WP_DISABLED =
- FLASHROM_OUTPUT_WP_PATTERN "disabled";
+static const char * const STR_REV = "rev";
/*
* Strips a string (usually from shell execution output) by removing all the
@@ -522,182 +515,6 @@ char *host_detect_servo(int *need_prepare_ptr)
return ret;
}
-// global to allow verbosity level to be injected into callback.
-static enum flashrom_log_level g_verbose_screen = FLASHROM_MSG_INFO;
-
-static int flashrom_print_cb(enum flashrom_log_level level, const char *fmt,
- va_list ap)
-{
- int ret = 0;
- FILE *output_type = (level < FLASHROM_MSG_INFO) ? stderr : stdout;
-
- if (level > g_verbose_screen)
- return ret;
-
- 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)
- 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_read(struct firmware_image *image)
-{
- int r = 0;
- size_t len = 0;
-
- char *programmer, *params;
- char *tmp = flashrom_extract_params(image->programmer, &programmer, &params);
-
- struct flashrom_programmer *prog = NULL;
- struct flashrom_flashctx *flashctx = 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);
- image->data = calloc(1, len);
- image->size = len;
- image->file_name = strdup("<none>");
-
- r |= flashrom_image_read(flashctx, image->data, len);
-
- r |= flashrom_programmer_shutdown(prog);
- flashrom_flash_release(flashctx);
- free(tmp);
-
- return r;
-}
-
-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, &params);
-
- 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_layout_set(flashctx, layout);
- }
-
- 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)
-{
- char *command, *result;
- const char *postfix;
- int r;
-
- /* grep is needed because host_shell only returns 1 line. */
- postfix = " 2>/dev/null | grep \"" FLASHROM_OUTPUT_WP_PATTERN "\"";
-
-
- /* TODO(b/203715651): link with flashrom directly. */
- ASPRINTF(&command, "flashrom --wp-status -p %s %s", programmer, postfix);
-
- /* invokes flashrom(8) with non-zero result if error. */
- result = host_shell(command);
- strip_string(result, NULL);
- free(command);
- VB2_DEBUG("wp-status: %s\n", result);
-
- if (strstr(result, FLASHROM_OUTPUT_WP_ENABLED))
- r = WP_ENABLED;
- else if (strstr(result, FLASHROM_OUTPUT_WP_DISABLED))
- r = WP_DISABLED;
- else
- r = WP_ERROR;
- free(result);
-
- return r;
-}
-
-/* Helper function to return host software write protection status. */
-static int host_get_wp_sw(void)
-{
- return host_get_wp(PROG_HOST);
-}
-
/*
* Loads the active system firmware image (usually from SPI flash chip).
* Returns 0 if success, non-zero if error.
@@ -707,8 +524,7 @@ int load_system_firmware(struct firmware_image *image,
{
int r;
- g_verbose_screen = verbosity + 1;
- r = host_flashrom_read(image);
+ r = flashrom_read_image(image, (verbosity + 1));
if (!r)
r = parse_firmware_image(image);
return r;
@@ -725,8 +541,13 @@ int write_system_firmware(const struct firmware_image *image,
struct tempfile *tempfiles,
int verbosity)
{
- g_verbose_screen = verbosity + 1;
- return host_flashrom_write(image, section_name, diff_image);
+ return flashrom_write_image(image, section_name, diff_image, (verbosity + 1));
+}
+
+/* Helper function to return host software write protection status. */
+static int host_get_wp_sw(void)
+{
+ return flashrom_get_wp(PROG_HOST);
}
/* Helper function to configure all properties. */
diff --git a/futility/updater_utils.h b/futility/updater_utils.h
index 25316757..2d64c295 100644
--- a/futility/updater_utils.h
+++ b/futility/updater_utils.h
@@ -175,7 +175,7 @@ enum wp_state {
};
/* Helper function to return write protection status via given programmer. */
-enum wp_state host_get_wp(const char *programmer);
+enum wp_state flashrom_get_wp(const char *programmer);
/* The environment variable name for setting servod port. */
#define ENV_SERVOD_PORT "SERVOD_PORT"
@@ -228,4 +228,10 @@ void init_system_properties(struct system_property *props, int num);
*/
const char *get_firmware_rootkey_hash(const struct firmware_image *image);
+int flashrom_read_image(struct firmware_image *image, int verbosity);
+int flashrom_write_image(const struct firmware_image *image,
+ const char *region,
+ const struct firmware_image *diff_image,
+ int verbosity);
+
#endif /* VBOOT_REFERENCE_FUTILITY_UPDATER_UTILS_H_ */