summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJi Luo <ji.luo@nxp.com>2020-06-09 14:59:45 +0800
committerJi Luo <ji.luo@nxp.com>2022-04-18 16:40:09 +0800
commit94a816ba1793cafe431e77e5bdd72f44ad4f8856 (patch)
tree122fe2ad38ab89339935bbc97fda3f79fe857605 /lib
parent260a680af5174d48d76931cf8fe86e7353636378 (diff)
MA-17338-1 Enable boot control v1.1
The old boot control logic and misc data struct is based on the 'external/avb/libavb_ab' library which is already marked as deprecated and won't be maintained by google anymore: commit 37f5946d0e1159273eff61dd8041377fedbf55a9 Author: David Zeuthen <zeuthen@google.com> Date: Wed Sep 20 15:02:32 2017 -0400 Deprecate libavb_ab and bootctrl.avb code. This code was already marked as experimental in anticipation of being removed in the future. Officially deprecate it and set Jun 1 2018 as the date it will be removed. This should give users of the code ample time to fork/migrate. To keep using the code AVB_AB_I_UNDERSTAND_LIBAVB_AB_IS_DEPRECATED must be defined. The reason for deprecating this code is twofold: - Its policy was optimized for devices without a display with e.g. automatic fallback to the other slot if a slot fails to boot. Since most A/B stacks in Android devices don't work this way this code is confusing. - There are no known active users, no good test coverage for the bootctrl.avb code, and no plans to use it. When the code is removed we'll provide an easy transition path by keeping (but renaming) the |ab_ops| member in AvbOps. Change-Id: Id5e090a2048076d36ccca2e1c4cb55e226b8b43d Google has provided a new boot control v1.1 implementation under 'hardware/interfaces/boot/1.1/default' which uses a new misc data struct defined in the 'include/android_bootloader_message.h'. This commit adds a new boot control implementation in bootloader, which combines the new misc data struct and inherit some flow in 'libavb_ab', the old 'libavb_ab' library will be removed. Test: boot/slot switch/retry count test on single&dual bootloader. Signed-off-by: Ji Luo <ji.luo@nxp.com> Change-Id: I0fa1ee8562c83afec549c8f6aad7a26a2214f626 (cherry picked from commit 29aafaf065d1688201d014213052863ec9d18e9c) (cherry picked from commit f5cda163c1559480a43e75869747a50787fd0ee1) (cherry picked from commit a45dca90ff92f548f157f8739a76f249ca8241cb)
Diffstat (limited to 'lib')
-rw-r--r--lib/avb/Makefile1
-rw-r--r--lib/avb/fsl/Makefile3
-rw-r--r--lib/avb/fsl/fsl_avb.c28
-rwxr-xr-xlib/avb/fsl/fsl_bootctl.c209
-rwxr-xr-x[-rw-r--r--]lib/avb/fsl/fsl_bootctrl.c (renamed from lib/avb/fsl/fsl_avb_ab_flow.c)668
-rw-r--r--lib/avb/fsl/fsl_bootctrl.h154
-rw-r--r--lib/avb/libavb_ab/Makefile2
-rw-r--r--lib/avb/libavb_ab/avb_ab_flow.c540
-rw-r--r--lib/avb/libavb_ab/avb_ab_flow.h267
-rw-r--r--lib/avb/libavb_ab/avb_ab_ops.h79
-rw-r--r--lib/avb/libavb_ab/libavb_ab.h51
11 files changed, 631 insertions, 1371 deletions
diff --git a/lib/avb/Makefile b/lib/avb/Makefile
index 0c5e2cf011..6841faf855 100644
--- a/lib/avb/Makefile
+++ b/lib/avb/Makefile
@@ -13,7 +13,6 @@ subdir-ccflags-y += -I./lib \
-std=gnu99
ifndef CONFIG_SPL_BUILD
-obj-y += libavb_ab/
obj-$(CONFIG_AVB_ATX) += libavb_atx/
endif
obj-y += fsl/
diff --git a/lib/avb/fsl/Makefile b/lib/avb/fsl/Makefile
index b209705252..f86ec7510d 100644
--- a/lib/avb/fsl/Makefile
+++ b/lib/avb/fsl/Makefile
@@ -1,9 +1,8 @@
ifndef CONFIG_SPL_BUILD
obj-y += fsl_avb.o
-obj-y += fsl_bootctl.o
endif
obj-y += fsl_avbkey.o
obj-y += utils.o
-obj-y += fsl_avb_ab_flow.o
+obj-y += fsl_bootctrl.o
obj-$(CONFIG_AVB_ATX) += fsl_atx_attributes.o
diff --git a/lib/avb/fsl/fsl_avb.c b/lib/avb/fsl/fsl_avb.c
index 3f6cc71b0a..fc67e949af 100644
--- a/lib/avb/fsl/fsl_avb.c
+++ b/lib/avb/fsl/fsl_avb.c
@@ -336,34 +336,6 @@ fail:
return ret;
}
-/* Reads A/B metadata from persistent storage. Returned data is
- * properly byteswapped. Returns AVB_IO_RESULT_OK on success, error
- * code otherwise.
- *
- * If the data read is invalid (e.g. wrong magic or CRC checksum
- * failure), the metadata shoule be reset using avb_ab_data_init()
- * and then written to persistent storage.
- *
- * Implementations will typically want to use avb_ab_data_read()
- * here to use the 'misc' partition for persistent storage.
- */
-AvbIOResult fsl_read_ab_metadata(AvbABOps* ab_ops, struct AvbABData* data)
-{
- return avb_ab_data_read(ab_ops, data);
-}
-
-/* Writes A/B metadata to persistent storage. This will byteswap and
- * update the CRC as needed. Returns AVB_IO_RESULT_OK on success,
- * error code otherwise.
- *
- * Implementations will typically want to use avb_ab_data_write()
- * here to use the 'misc' partition for persistent storage.
- */
-AvbIOResult fsl_write_ab_metadata(AvbABOps* ab_ops, const struct AvbABData* data)
-{
- return avb_ab_data_write(ab_ops, data);
-}
-
/* Gets whether the device is unlocked. The value is returned in
* |out_is_unlocked| (true if unlocked, false otherwise). Returns
* AVB_IO_RESULT_OK if the state was retrieved, otherwise an error
diff --git a/lib/avb/fsl/fsl_bootctl.c b/lib/avb/fsl/fsl_bootctl.c
deleted file mode 100755
index 1143c3f088..0000000000
--- a/lib/avb/fsl/fsl_bootctl.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2016 Freescale Semiconductor, Inc.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <stdlib.h>
-#include <linux/string.h>
-#include <fb_fsl.h>
-#include <fsl_avb.h>
-
-/* as libavb's bootctl doesn't have the get_var support
- * we add the getvar support on our side ...*/
-#ifndef MAX_PTN
-#define MAX_PTN 32
-#endif
-#define SLOT_NUM 2
-static char *slot_suffix[SLOT_NUM] = {"_a", "_b"};
-
-static int strcmp_l1(const char *s1, const char *s2) {
- if (!s1 || !s2)
- return -1;
- return strncmp(s1, s2, strlen(s1));
-}
-
-static bool slot_is_bootable(AvbABSlotData* slot) {
-#ifdef CONFIG_DUAL_BOOTLOADER
- /* The 'bootloader_verified' will be set when the slot has only one chance
- * left, which means the slot is bootable even tries_remaining is 0.
- */
- return slot->priority > 0 &&
- (slot->successful_boot || (slot->tries_remaining > 0)
- || (slot->bootloader_verified == 1));
-#else
- return slot->priority > 0 &&
- (slot->successful_boot || (slot->tries_remaining > 0));
-#endif
-}
-
-int slotidx_from_suffix(char *suffix) {
- int slot = -1;
-
- if (!strcmp(suffix, "_a") ||
- !strcmp(suffix, "a"))
- slot = 0;
- else if (!strcmp(suffix, "_b") ||
- !strcmp(suffix, "b"))
- slot = 1;
-
- return slot;
-}
-
-bool is_slotvar_avb(char *cmd) {
-
- assert(cmd != NULL);
- if (!strcmp_l1("has-slot:", cmd) ||
- !strcmp_l1("slot-successful:", cmd) ||
- !strcmp_l1("slot-count", cmd) ||
- !strcmp_l1("slot-suffixes", cmd) ||
- !strcmp_l1("current-slot", cmd) ||
- !strcmp_l1("slot-unbootable:", cmd) ||
- !strcmp_l1("slot-retry-count:", cmd))
- return true;
- return false;
-}
-
-int get_curr_slot(AvbABData *ab_data) {
- if (slot_is_bootable(&ab_data->slots[0]) &&
- slot_is_bootable(&ab_data->slots[1])) {
- if (ab_data->slots[1].priority > ab_data->slots[0].priority)
- return 1;
- else
- return 0;
- } else if (slot_is_bootable(&ab_data->slots[0]))
- return 0;
- else if (slot_is_bootable(&ab_data->slots[1]))
- return 1;
- else
- return -1;
-}
-
-extern struct fastboot_ptentry g_ptable[MAX_PTN];
-extern unsigned int g_pcount;
-
-static bool has_slot(char *cmd) {
- unsigned int n;
- char *ptr;
-
- for (n = 0; n < g_pcount; n++) {
- ptr = strstr(g_ptable[n].name, cmd);
- if (ptr != NULL) {
- ptr += strlen(cmd);
- if (!strcmp(ptr, "_a") || !strcmp(ptr, "_b"))
- return true;
- }
- }
- return false;
-}
-
-int get_slotvar_avb(AvbABOps *ab_ops, char *cmd, char *buffer, size_t size) {
-
- AvbABData ab_data;
- AvbABSlotData *slot_data;
- int slot;
-
- if ((ab_ops == NULL) || (cmd == NULL) || (buffer == NULL))
- return -1;
-
- char *str = cmd;
- if (!strcmp_l1("has-slot:", cmd)) {
- str += strlen("has-slot:");
- if (has_slot(str))
- strlcpy(buffer, "yes", size);
- else
- strlcpy(buffer, "no", size);
- return 0;
-
- } else if (!strcmp_l1("slot-suffixes", cmd)) {
- strlcpy(buffer, "_a,_b", size);
- return 0 ;
-
- } else if (!strcmp_l1("slot-count", cmd)) {
- strlcpy(buffer, "2", size);
- return 0 ;
- }
-
- /* load ab meta */
- if (ab_ops->read_ab_metadata == NULL ||
- ab_ops->read_ab_metadata(ab_ops, &ab_data) != AVB_IO_RESULT_OK) {
- strlcpy(buffer, "ab data read error", size);
- return -1 ;
- }
-
- if (!strcmp_l1("current-slot", cmd)) {
- int curr = get_curr_slot(&ab_data);
- if (curr >= 0 && curr < SLOT_NUM)
- strlcpy(buffer, slot_suffix[curr] + sizeof(unsigned char), size);
- else {
- strlcpy(buffer, "no bootable slot", size);
- return -1;
- }
-
- } else if (!strcmp_l1("slot-successful:", cmd)) {
- str += strlen("slot-successful:");
- slot = slotidx_from_suffix(str);
- if (slot < 0) {
- strlcpy(buffer, "no such slot", size);
- return -1;
- } else {
- slot_data = &ab_data.slots[slot];
- bool succ = (slot_data->successful_boot != 0);
- strlcpy(buffer, succ ? "yes" : "no", size);
- }
-
- } else if (!strcmp_l1("slot-unbootable:", cmd)) {
- str += strlen("slot-unbootable:");
- slot = slotidx_from_suffix(str);
- if (slot < 0) {
- strlcpy(buffer, "no such slot", size);
- return -1;
- } else {
- slot_data = &ab_data.slots[slot];
- bool bootable = slot_is_bootable(slot_data);
- strlcpy(buffer, bootable ? "no" : "yes", size);
- }
-
- } else if (!strcmp_l1("slot-retry-count:", cmd)) {
- str += strlen("slot-retry-count:");
- slot = slotidx_from_suffix(str);
- if (slot < 0) {
- strlcpy(buffer, "no such slot", size);
- return -1;
- }
- else {
- slot_data = &ab_data.slots[slot];
- char var[7];
- sprintf(var, "%d",
- slot_data->tries_remaining);
- strlcpy(buffer, var, size);
- }
-
- } else {
- strlcpy(buffer, "no such slot command", size);
- return -1;
- }
-
- return 0;
-}
-
-char *select_slot(AvbABOps *ab_ops) {
- AvbABData ab_data;
- int curr;
-
- if (ab_ops == NULL) {
- return NULL;
- }
-
- /* load ab meta */
- if (ab_ops->read_ab_metadata == NULL ||
- ab_ops->read_ab_metadata(ab_ops, &ab_data) != AVB_IO_RESULT_OK) {
- return NULL;
- }
- curr = get_curr_slot(&ab_data);
- if (curr >= 0 && curr < SLOT_NUM)
- return slot_suffix[curr];
- else
- return NULL;
-}
diff --git a/lib/avb/fsl/fsl_avb_ab_flow.c b/lib/avb/fsl/fsl_bootctrl.c
index bf9ac53f2a..688d0472a2 100644..100755
--- a/lib/avb/fsl/fsl_avb_ab_flow.c
+++ b/lib/avb/fsl/fsl_bootctrl.c
@@ -1,151 +1,474 @@
/*
- * Copyright 2018 NXP
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Copyright 2020 NXP
+ *
*/
#include <common.h>
-#include <fsl_avb.h>
+#include <stdlib.h>
+#include <linux/string.h>
#include <mmc.h>
#include <spl.h>
#include <part.h>
-#include <image.h>
#include "utils.h"
-#include "fsl_caam.h"
+#include <fb_fsl.h>
+#include <fsl_avb.h>
+#include <image.h>
+#include <hang.h>
#include "fsl_avbkey.h"
#include "hang.h"
+#include "fsl_bootctrl.h"
+
+/* Maximum values for slot data */
+#define AVB_AB_MAX_PRIORITY 15
+#define AVB_AB_MAX_TRIES_REMAINING 7
+#define AVB_AB_SLOT_NUM 2
+#ifndef MAX_PTN
+#define MAX_PTN 32
+#endif
-#if defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
-static const char* slot_suffixes[2] = {"_a", "_b"};
-
-/* This is a copy of slot_set_unbootable() form
- * external/avb/libavb_ab/avb_ab_flow.c.
+/* The bootloader_control struct is stored 2048 bytes into the 'misc' partition
+ * following the 'struct bootloader_message' field. The struct is compatible with
+ * the guidelines in
+ * hardware/interfaces/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
*/
-void fsl_slot_set_unbootable(AvbABSlotData* slot) {
+#define FSL_AB_METADATA_MISC_PARTITION_OFFSET 2048
+
+static char *slot_suffix[AVB_AB_SLOT_NUM] = {"_a", "_b"};
+
+static int strcmp_l1(const char *s1, const char *s2) {
+ if (!s1 || !s2)
+ return -1;
+ return strncmp(s1, s2, strlen(s1));
+}
+
+int get_curr_slot(struct bootloader_control *ab_data) {
+ if (fsl_slot_is_bootable(&ab_data->slot_info[0]) &&
+ fsl_slot_is_bootable(&ab_data->slot_info[1])) {
+ if (ab_data->slot_info[1].priority > ab_data->slot_info[0].priority)
+ return 1;
+ else
+ return 0;
+ } else if (fsl_slot_is_bootable(&ab_data->slot_info[0]))
+ return 0;
+ else if (fsl_slot_is_bootable(&ab_data->slot_info[1]))
+ return 1;
+ else
+ return -1;
+}
+
+int slotidx_from_suffix(char *suffix) {
+ int slot = -1;
+
+ if (!strcmp(suffix, "_a") ||
+ !strcmp(suffix, "a"))
+ slot = 0;
+ else if (!strcmp(suffix, "_b") ||
+ !strcmp(suffix, "b"))
+ slot = 1;
+
+ return slot;
+}
+
+bool is_slotvar_avb(char *cmd) {
+
+ assert(cmd != NULL);
+ if (!strcmp_l1("has-slot:", cmd) ||
+ !strcmp_l1("slot-successful:", cmd) ||
+ !strcmp_l1("slot-count", cmd) ||
+ !strcmp_l1("slot-suffixes", cmd) ||
+ !strcmp_l1("current-slot", cmd) ||
+ !strcmp_l1("slot-unbootable:", cmd) ||
+ !strcmp_l1("slot-retry-count:", cmd))
+ return true;
+ return false;
+}
+
+extern struct fastboot_ptentry g_ptable[MAX_PTN];
+extern unsigned int g_pcount;
+
+static bool has_slot(char *cmd) {
+ unsigned int n;
+ char *ptr;
+
+ for (n = 0; n < g_pcount; n++) {
+ ptr = strstr(g_ptable[n].name, cmd);
+ if (ptr != NULL) {
+ ptr += strlen(cmd);
+ if (!strcmp(ptr, "_a") || !strcmp(ptr, "_b"))
+ return true;
+ }
+ }
+ return false;
+}
+
+int get_slotvar_avb(AvbABOps *ab_ops, char *cmd, char *buffer, size_t size) {
+
+ struct bootloader_control ab_data;
+ struct slot_metadata *slot_data;
+ int slot;
+
+ if ((ab_ops == NULL) || (cmd == NULL) || (buffer == NULL))
+ return -1;
+
+ char *str = cmd;
+ if (!strcmp_l1("has-slot:", cmd)) {
+ str += strlen("has-slot:");
+ if (has_slot(str))
+ strlcpy(buffer, "yes", size);
+ else
+ strlcpy(buffer, "no", size);
+ return 0;
+
+ } else if (!strcmp_l1("slot-suffixes", cmd)) {
+ strlcpy(buffer, "_a,_b", size);
+ return 0 ;
+
+ } else if (!strcmp_l1("slot-count", cmd)) {
+ strlcpy(buffer, "2", size);
+ return 0 ;
+ }
+
+ /* load ab meta */
+ if (ab_ops->read_ab_metadata == NULL ||
+ ab_ops->read_ab_metadata(ab_ops, &ab_data) != AVB_IO_RESULT_OK) {
+ strlcpy(buffer, "ab data read error", size);
+ return -1 ;
+ }
+
+ if (!strcmp_l1("current-slot", cmd)) {
+ int curr = get_curr_slot(&ab_data);
+ if (curr >= 0 && curr < AVB_AB_SLOT_NUM)
+ strlcpy(buffer, slot_suffix[curr] + sizeof(unsigned char), size);
+ else {
+ strlcpy(buffer, "no bootable slot", size);
+ return -1;
+ }
+
+ } else if (!strcmp_l1("slot-successful:", cmd)) {
+ str += strlen("slot-successful:");
+ slot = slotidx_from_suffix(str);
+ if (slot < 0) {
+ strlcpy(buffer, "no such slot", size);
+ return -1;
+ } else {
+ slot_data = &ab_data.slot_info[slot];
+ bool succ = (slot_data->successful_boot != 0);
+ strlcpy(buffer, succ ? "yes" : "no", size);
+ }
+
+ } else if (!strcmp_l1("slot-unbootable:", cmd)) {
+ str += strlen("slot-unbootable:");
+ slot = slotidx_from_suffix(str);
+ if (slot < 0) {
+ strlcpy(buffer, "no such slot", size);
+ return -1;
+ } else {
+ slot_data = &ab_data.slot_info[slot];
+ bool bootable = fsl_slot_is_bootable(slot_data);
+ strlcpy(buffer, bootable ? "no" : "yes", size);
+ }
+
+ } else if (!strcmp_l1("slot-retry-count:", cmd)) {
+ str += strlen("slot-retry-count:");
+ slot = slotidx_from_suffix(str);
+ if (slot < 0) {
+ strlcpy(buffer, "no such slot", size);
+ return -1;
+ }
+ else {
+ slot_data = &ab_data.slot_info[slot];
+ char var[7];
+ sprintf(var, "%d",
+ slot_data->tries_remaining);
+ strlcpy(buffer, var, size);
+ }
+
+ } else {
+ strlcpy(buffer, "no such slot command", size);
+ return -1;
+ }
+
+ return 0;
+}
+
+char *select_slot(AvbABOps *ab_ops) {
+ struct bootloader_control ab_data;
+ int curr;
+
+ if (ab_ops == NULL) {
+ return NULL;
+ }
+
+ /* load ab meta */
+ if (ab_ops->read_ab_metadata == NULL ||
+ ab_ops->read_ab_metadata(ab_ops, &ab_data) != AVB_IO_RESULT_OK) {
+ return NULL;
+ }
+ curr = get_curr_slot(&ab_data);
+ if (curr >= 0 && curr < AVB_AB_SLOT_NUM)
+ return slot_suffix[curr];
+ else
+ return NULL;
+}
+
+bool fsl_avb_ab_data_verify_and_byteswap(const struct bootloader_control* src,
+ struct bootloader_control* dest) {
+ /* Ensure magic is correct. */
+ if (src->magic != BOOT_CTRL_MAGIC) {
+ printf("Magic is incorrect.\n");
+ return false;
+ }
+
+ memcpy(dest, src, sizeof(struct bootloader_control));
+
+ /* Ensure we don't attempt to access any fields if the bootctrl version
+ * is not supported.
+ */
+ if (dest->version > BOOT_CTRL_VERSION) {
+ printf("No support for given bootctrl version.\n");
+ return false;
+ }
+
+ /* Fail if CRC32 doesn't match. */
+ if (dest->crc32_le !=
+ avb_crc32((const uint8_t*)dest, sizeof(struct bootloader_control) - sizeof(uint32_t))) {
+ printf("CRC32 does not match.\n");
+ return false;
+ }
+
+ return true;
+}
+
+void fsl_avb_ab_data_update_crc_and_byteswap(const struct bootloader_control* src,
+ struct bootloader_control* dest) {
+ memcpy(dest, src, sizeof(struct bootloader_control));
+ dest->crc32_le = avb_crc32((const uint8_t*)dest,
+ sizeof(struct bootloader_control) - sizeof(uint32_t));
+}
+
+void fsl_avb_ab_data_init(struct bootloader_control* data) {
+ memset(data, '\0', sizeof(struct bootloader_control));
+ data->magic = BOOT_CTRL_MAGIC;
+ data->version = BOOT_CTRL_VERSION;
+ // this bootctrl can support up to 4 slots but here we only support 2
+ data->nb_slot = AVB_AB_SLOT_NUM;
+ data->slot_info[0].priority = AVB_AB_MAX_PRIORITY;
+ data->slot_info[0].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
+ data->slot_info[0].successful_boot = 0;
+ data->slot_info[0].verity_corrupted = 0;
+#ifdef CONFIG_DUAL_BOOTLOADER
+ data->slot_info[0].bootloader_verified = 0;
+#endif
+ data->slot_info[1].priority = AVB_AB_MAX_PRIORITY;
+ data->slot_info[1].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
+ data->slot_info[1].successful_boot = 0;
+ data->slot_info[1].verity_corrupted = 0;
+#ifdef CONFIG_DUAL_BOOTLOADER
+ data->slot_info[1].bootloader_verified = 0;
+#endif
+}
+
+AvbIOResult fsl_avb_ab_data_read(AvbABOps* ab_ops, struct bootloader_control* data) {
+ AvbOps* ops = ab_ops->ops;
+ struct bootloader_control serialized;
+ AvbIOResult io_ret;
+ size_t num_bytes_read;
+
+ io_ret = ops->read_from_partition(ops,
+ FASTBOOT_PARTITION_MISC,
+ FSL_AB_METADATA_MISC_PARTITION_OFFSET,
+ sizeof(struct bootloader_control),
+ &serialized,
+ &num_bytes_read);
+ if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+ return AVB_IO_RESULT_ERROR_OOM;
+ } else if (io_ret != AVB_IO_RESULT_OK ||
+ num_bytes_read != sizeof(struct bootloader_control)) {
+ printf("Error reading A/B metadata.\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+
+ if (!fsl_avb_ab_data_verify_and_byteswap(&serialized, data)) {
+ printf(
+ "Error validating A/B metadata from disk. "
+ "Resetting and writing new A/B metadata to disk.\n");
+ fsl_avb_ab_data_init(data);
+ return fsl_avb_ab_data_write(ab_ops, data);
+ }
+
+ return AVB_IO_RESULT_OK;
+}
+
+AvbIOResult fsl_avb_ab_data_write(AvbABOps* ab_ops, const struct bootloader_control* data) {
+ AvbOps* ops = ab_ops->ops;
+ struct bootloader_control serialized;
+ AvbIOResult io_ret;
+
+ fsl_avb_ab_data_update_crc_and_byteswap(data, &serialized);
+ io_ret = ops->write_to_partition(ops,
+ FASTBOOT_PARTITION_MISC,
+ FSL_AB_METADATA_MISC_PARTITION_OFFSET,
+ sizeof(struct bootloader_control),
+ &serialized);
+ if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+ return AVB_IO_RESULT_ERROR_OOM;
+ } else if (io_ret != AVB_IO_RESULT_OK) {
+ printf("Error writing A/B metadata.\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+ return AVB_IO_RESULT_OK;
+}
+
+bool fsl_slot_is_bootable(struct slot_metadata* slot) {
+#ifdef CONFIG_DUAL_BOOTLOADER
+ /* The 'bootloader_verified' will be set when the slot has only one chance
+ * left, which means the slot is bootable even tries_remaining is 0.
+ */
+ return slot->priority > 0 &&
+ (slot->successful_boot || (slot->tries_remaining > 0)||
+ (slot->bootloader_verified == 1));
+#else
+ return slot->priority > 0 &&
+ (slot->successful_boot || (slot->tries_remaining > 0));
+#endif
+}
+
+static void fsl_slot_set_unbootable(struct slot_metadata* slot) {
slot->priority = 0;
slot->tries_remaining = 0;
slot->successful_boot = 0;
+#ifdef CONFIG_DUAL_BOOTLOADER
+ slot->bootloader_verified = 0;
+#endif
}
/* Ensure all unbootable and/or illegal states are marked as the
* canonical 'unbootable' state, e.g. priority=0, tries_remaining=0,
- * and successful_boot=0. This is a copy of slot_normalize from
- * external/avb/libavb_ab/avb_ab_flow.c.
+ * and successful_boot=0.
*/
-void fsl_slot_normalize(AvbABSlotData* slot) {
+static void fsl_slot_normalize(struct slot_metadata* slot) {
if (slot->priority > 0) {
#if defined(CONFIG_DUAL_BOOTLOADER) && !defined(CONFIG_SPL_BUILD)
if ((slot->tries_remaining == 0)
- && (!slot->successful_boot) && (slot->bootloader_verified != 1)) {
+ && (slot->bootloader_verified != 1)) {
/* We've exhausted all tries -> unbootable. */
fsl_slot_set_unbootable(slot);
}
#else
- if ((slot->tries_remaining == 0) && (!slot->successful_boot)) {
+ if (slot->tries_remaining == 0) {
/* We've exhausted all tries -> unbootable. */
fsl_slot_set_unbootable(slot);
}
#endif
- if ((slot->tries_remaining > 0) && (slot->successful_boot)) {
- /* Illegal state - avb_ab_mark_slot_successful() will clear
- * tries_remaining when setting successful_boot.
- */
- fsl_slot_set_unbootable(slot);
- }
} else {
fsl_slot_set_unbootable(slot);
}
}
-/* This is a copy of slot_is_bootable() from
- * externel/avb/libavb_ab/avb_ab_flow.c.
+/* Helper function to load metadata - returns AVB_IO_RESULT_OK on
+ * success, error code otherwise.
*/
-bool fsl_slot_is_bootable(AvbABSlotData* slot) {
- return (slot->priority > 0) &&
- (slot->successful_boot || (slot->tries_remaining > 0));
-}
-#endif /* CONFIG_DUAL_BOOTLOADER || !CONFIG_SPL_BUILD */
-
-#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD)
+static AvbIOResult fsl_load_metadata(AvbABOps* ab_ops,
+ struct bootloader_control* ab_data,
+ struct bootloader_control* ab_data_orig) {
+ AvbIOResult io_ret;
-#define FSL_AB_METADATA_MISC_PARTITION_OFFSET 2048
-#define PARTITION_NAME_LEN 13
-#define PARTITION_MISC "misc"
-#define PARTITION_BOOTLOADER "bootloader"
+ io_ret = ab_ops->read_ab_metadata(ab_ops, ab_data);
+ if (io_ret != AVB_IO_RESULT_OK) {
+ printf("I/O error while loading A/B metadata.\n");
+ return io_ret;
+ }
+ *ab_data_orig = *ab_data;
-extern int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value);
-extern int mmc_load_image_parse_container(struct spl_image_info *spl_image,
- struct mmc *mmc, unsigned long sector);
+ /* Ensure data is normalized, e.g. illegal states will be marked as
+ * unbootable and all unbootable states are represented with
+ * (priority=0, tries_remaining=0, successful_boot=0).
+ */
+ fsl_slot_normalize(&ab_data->slot_info[0]);
+ fsl_slot_normalize(&ab_data->slot_info[1]);
+ return AVB_IO_RESULT_OK;
+}
-/* Pre-declaration of h_spl_load_read(), see detail implementation in
- * common/spl/spl_mmc.c.
+/* Writes A/B metadata to disk only if it has been changed.
*/
-ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
- ulong count, void *buf);
-
-void fsl_avb_ab_data_update_crc_and_byteswap(const AvbABData* src,
- AvbABData* dest) {
- memcpy(dest, src, sizeof(AvbABData));
- dest->crc32 = cpu_to_be32(
- avb_crc32((const uint8_t*)dest,
- sizeof(AvbABData) - sizeof(uint32_t)));
+static AvbIOResult fsl_save_metadata_if_changed(AvbABOps* ab_ops,
+ struct bootloader_control* ab_data,
+ struct bootloader_control* ab_data_orig) {
+ if (avb_safe_memcmp(ab_data, ab_data_orig, sizeof(struct bootloader_control)) != 0) {
+ printf("Writing A/B metadata to disk.\n");
+ return ab_ops->write_ab_metadata(ab_ops, ab_data);
+ }
+ return AVB_IO_RESULT_OK;
}
-void fsl_avb_ab_data_init(AvbABData* data) {
- memset(data, '\0', sizeof(AvbABData));
- memcpy(data->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN);
- data->version_major = AVB_AB_MAJOR_VERSION;
- data->version_minor = AVB_AB_MINOR_VERSION;
- data->slots[0].priority = AVB_AB_MAX_PRIORITY;
- data->slots[0].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
- data->slots[0].successful_boot = 0;
- data->slots[0].bootloader_verified = 0;
- data->slots[1].priority = AVB_AB_MAX_PRIORITY - 1;
- data->slots[1].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
- data->slots[1].successful_boot = 0;
- data->slots[1].bootloader_verified = 0;
-}
+AvbIOResult fsl_avb_ab_mark_slot_active(AvbABOps* ab_ops,
+ unsigned int slot_number) {
+ struct bootloader_control ab_data, ab_data_orig;
+ unsigned int other_slot_number;
+ AvbIOResult ret;
-bool fsl_avb_ab_data_verify_and_byteswap(const AvbABData* src,
- AvbABData* dest) {
- /* Ensure magic is correct. */
- if (memcmp(src->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN) != 0) {
- printf("Magic is incorrect.\n");
- return false;
+ avb_assert(slot_number < 2);
+
+ ret = fsl_load_metadata(ab_ops, &ab_data, &ab_data_orig);
+ if (ret != AVB_IO_RESULT_OK) {
+ goto out;
}
- memcpy(dest, src, sizeof(AvbABData));
- dest->crc32 = be32_to_cpu(dest->crc32);
+ /* Make requested slot top priority, unsuccessful, and with max tries. */
+ ab_data.slot_info[slot_number].priority = AVB_AB_MAX_PRIORITY;
+ ab_data.slot_info[slot_number].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
+ ab_data.slot_info[slot_number].successful_boot = 0;
+#ifdef CONFIG_DUAL_BOOTLOADER
+ ab_data.slot_info[slot_number].bootloader_verified = 0;
+#endif
- /* Ensure we don't attempt to access any fields if the major version
- * is not supported.
- */
- if (dest->version_major > AVB_AB_MAJOR_VERSION) {
- printf("No support for given major version.\n");
- return false;
+ /* Ensure other slot doesn't have as high a priority. */
+ other_slot_number = 1 - slot_number;
+ if (ab_data.slot_info[other_slot_number].priority == AVB_AB_MAX_PRIORITY) {
+ ab_data.slot_info[other_slot_number].priority = AVB_AB_MAX_PRIORITY - 1;
}
- /* Fail if CRC32 doesn't match. */
- if (dest->crc32 !=
- avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t))) {
- printf("CRC32 does not match.\n");
- return false;
- }
+ ret = AVB_IO_RESULT_OK;
- return true;
+out:
+ if (ret == AVB_IO_RESULT_OK) {
+ ret = fsl_save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
+ }
+ return ret;
}
+
+/* Below are the A/B AVB flow in spl and uboot proper. */
+#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD)
+
+#define PARTITION_NAME_LEN 13
+#define PARTITION_BOOTLOADER "bootloader"
+
+extern int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value);
+
+/* Pre-declaration of h_spl_load_read(), see detail implementation in
+ * common/spl/spl_mmc.c.
+ */
+ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf);
+
/* Writes A/B metadata to disk only if it has changed.
*/
int fsl_save_metadata_if_changed_dual_uboot(struct blk_desc *dev_desc,
- AvbABData* ab_data,
- AvbABData* ab_data_orig) {
- AvbABData serialized;
+ struct bootloader_control* ab_data,
+ struct bootloader_control* ab_data_orig) {
+ struct bootloader_control serialized;
size_t num_bytes;
struct disk_partition info;
/* Save metadata if changed. */
- if (memcmp(ab_data, ab_data_orig, sizeof(AvbABData)) != 0) {
+ if (memcmp(ab_data, ab_data_orig, sizeof(struct bootloader_control)) != 0) {
/* Get misc partition info */
- if (part_get_info_by_name(dev_desc, PARTITION_MISC, &info) == -1) {
+ if (part_get_info_by_name(dev_desc, FASTBOOT_PARTITION_MISC, &info) == -1) {
printf("Can't get partition info of partition: misc\n");
return -1;
}
@@ -153,10 +476,10 @@ int fsl_save_metadata_if_changed_dual_uboot(struct blk_desc *dev_desc,
/* Writing A/B metadata to disk. */
fsl_avb_ab_data_update_crc_and_byteswap(ab_data, &serialized);
if (write_to_partition_in_bytes(dev_desc, &info,
- FSL_AB_METADATA_MISC_PARTITION_OFFSET,
- sizeof(AvbABData),
- (void *)&serialized, &num_bytes) ||
- (num_bytes != sizeof(AvbABData))) {
+ FSL_AB_METADATA_MISC_PARTITION_OFFSET,
+ sizeof(struct bootloader_control),
+ (void *)&serialized, &num_bytes) ||
+ (num_bytes != sizeof(struct bootloader_control))) {
printf("Error--write metadata fail!\n");
return -1;
}
@@ -167,21 +490,21 @@ int fsl_save_metadata_if_changed_dual_uboot(struct blk_desc *dev_desc,
/* Load metadate from misc partition.
*/
int fsl_load_metadata_dual_uboot(struct blk_desc *dev_desc,
- AvbABData* ab_data,
- AvbABData* ab_data_orig) {
+ struct bootloader_control* ab_data,
+ struct bootloader_control* ab_data_orig) {
struct disk_partition info;
- AvbABData serialized;
+ struct bootloader_control serialized;
size_t num_bytes;
- if (part_get_info_by_name(dev_desc, PARTITION_MISC, &info) == -1) {
+ if (part_get_info_by_name(dev_desc, FASTBOOT_PARTITION_MISC, &info) == -1) {
printf("Can't get partition info of partition: misc\n");
return -1;
} else {
read_from_partition_in_bytes(dev_desc, &info,
FSL_AB_METADATA_MISC_PARTITION_OFFSET,
- sizeof(AvbABData),
+ sizeof(struct bootloader_control),
(void *)ab_data, &num_bytes );
- if (num_bytes != sizeof(AvbABData)) {
+ if (num_bytes != sizeof(struct bootloader_control)) {
printf("Error--read metadata fail!\n");
return -1;
} else {
@@ -191,24 +514,22 @@ int fsl_load_metadata_dual_uboot(struct blk_desc *dev_desc,
fsl_avb_ab_data_init(ab_data);
fsl_avb_ab_data_update_crc_and_byteswap(ab_data, &serialized);
num_bytes = 0;
- if (write_to_partition_in_bytes(
- dev_desc, &info,
- FSL_AB_METADATA_MISC_PARTITION_OFFSET,
- sizeof(AvbABData),
- (void *)&serialized, &num_bytes) ||
- (num_bytes != sizeof(AvbABData))) {
+ if (write_to_partition_in_bytes(dev_desc, &info, FSL_AB_METADATA_MISC_PARTITION_OFFSET,
+ sizeof(struct bootloader_control),
+ (void *)&serialized, &num_bytes) ||
+ (num_bytes != sizeof(struct bootloader_control))) {
printf("Error--write metadata fail!\n");
return -1;
} else
return 0;
} else {
- memcpy(ab_data_orig, ab_data, sizeof(AvbABData));
+ memcpy(ab_data_orig, ab_data, sizeof(struct bootloader_control));
/* Ensure data is normalized, e.g. illegal states will be marked as
* unbootable and all unbootable states are represented with
* (priority=0, tries_remaining=0, successful_boot=0).
*/
- fsl_slot_normalize(&ab_data->slots[0]);
- fsl_slot_normalize(&ab_data->slots[1]);
+ fsl_slot_normalize(&ab_data->slot_info[0]);
+ fsl_slot_normalize(&ab_data->slot_info[1]);
return 0;
}
}
@@ -216,7 +537,7 @@ int fsl_load_metadata_dual_uboot(struct blk_desc *dev_desc,
}
#if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS)
-static int spl_verify_rbidx(struct mmc *mmc, AvbABSlotData *slot,
+static int spl_verify_rbidx(struct mmc *mmc, struct slot_metadata *slot,
struct spl_image_info *spl_image)
{
kblb_hdr_t hdr;
@@ -287,7 +608,7 @@ int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image,
struct blk_desc *dev_desc;
struct image_header *header;
struct spl_load_info load;
- AvbABData ab_data, ab_data_orig;
+ struct bootloader_control ab_data, ab_data_orig;
size_t slot_index_to_boot, target_slot;
#if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS)
struct keyslot_package kp;
@@ -330,22 +651,22 @@ int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image,
slot_index_to_boot = 2; // Means not 0 or 1
target_slot =
- (ab_data.slots[1].priority > ab_data.slots[0].priority) ? 1 : 0;
+ (ab_data.slot_info[1].priority > ab_data.slot_info[0].priority) ? 1 : 0;
for (n = 0; n < 2; n++) {
- if (!fsl_slot_is_bootable(&ab_data.slots[target_slot])) {
+ if (!fsl_slot_is_bootable(&ab_data.slot_info[target_slot])) {
target_slot = (target_slot == 1 ? 0 : 1);
continue;
}
/* Choose slot to load. */
snprintf(partition_name, PARTITION_NAME_LEN,
PARTITION_BOOTLOADER"%s",
- slot_suffixes[target_slot]);
+ slot_suffix[target_slot]);
/* Read part info from gpt */
if (part_get_info_by_name(dev_desc, partition_name, &info) == -1) {
printf("Can't get partition info of partition bootloader%s\n",
- slot_suffixes[target_slot]);
+ slot_suffix[target_slot]);
ret = -1;
goto end;
} else {
@@ -380,7 +701,7 @@ int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image,
/* Image loaded successfully, go to verify rollback index */
if (rpmbkey_is_set()) {
if (!ret)
- ret = spl_verify_rbidx(mmc, &ab_data.slots[target_slot], spl_image);
+ ret = spl_verify_rbidx(mmc, &ab_data.slot_info[target_slot], spl_image);
/* Copy rpmb keyslot to secure memory. */
if (!ret)
@@ -395,12 +716,12 @@ int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image,
* slot been marked as "unbootable" due to some random failures (like
* eMMC/DRAM access error at some critical temperature).
*/
- if (ab_data.slots[target_slot].successful_boot)
+ if (ab_data.slot_info[target_slot].successful_boot)
do_reset(NULL, 0, 0, NULL);
else {
printf("Load or verify bootloader%s fail, setting unbootable..\n",
- slot_suffixes[target_slot]);
- fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
+ slot_suffix[target_slot]);
+ fsl_slot_set_unbootable(&ab_data.slot_info[target_slot]);
/* Switch to another slot. */
target_slot = (target_slot == 1 ? 0 : 1);
}
@@ -422,12 +743,12 @@ int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image,
snprintf(partition_name, PARTITION_NAME_LEN,
PARTITION_BOOTLOADER"%s",
- slot_suffixes[target_slot]);
+ slot_suffix[target_slot]);
/* Read part info from gpt */
if (part_get_info_by_name(dev_desc, partition_name, &info) == -1) {
printf("Can't get partition info of partition bootloader%s\n",
- slot_suffixes[target_slot]);
+ slot_suffix[target_slot]);
ret = -1;
goto end;
} else {
@@ -462,7 +783,7 @@ int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image,
/* Image loaded successfully, go to verify rollback index */
if (rpmbkey_is_set()) {
if (!ret)
- ret = spl_verify_rbidx(mmc, &ab_data.slots[target_slot], spl_image);
+ ret = spl_verify_rbidx(mmc, &ab_data.slot_info[target_slot], spl_image);
/* Copy rpmb keyslot to secure memory. */
if (!ret)
@@ -473,16 +794,16 @@ int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image,
if (ret)
goto end;
- } else if (!ab_data.slots[slot_index_to_boot].successful_boot &&
- (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) {
+ } else if (!ab_data.slot_info[slot_index_to_boot].successful_boot &&
+ (ab_data.slot_info[slot_index_to_boot].tries_remaining > 0)) {
/* Set the bootloader_verified flag as if current slot only has one chance. */
- if (ab_data.slots[slot_index_to_boot].tries_remaining == 1)
- ab_data.slots[slot_index_to_boot].bootloader_verified = 1;
- ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
+ if (ab_data.slot_info[slot_index_to_boot].tries_remaining == 1)
+ ab_data.slot_info[slot_index_to_boot].bootloader_verified = 1;
+ ab_data.slot_info[slot_index_to_boot].tries_remaining -= 1;
ab_data.last_boot = slot_index_to_boot;
}
- printf("Booting from bootloader%s...\n", slot_suffixes[slot_index_to_boot]);
+ printf("Booting from bootloader%s...\n", slot_suffix[slot_index_to_boot]);
end:
/* Save metadata if changed. */
@@ -529,44 +850,8 @@ int spl_fit_get_rbindex(const void *fit)
/* For normal build */
#elif !defined(CONFIG_SPL_BUILD)
-/* Writes A/B metadata to disk only if it has been changed.
- */
-static AvbIOResult fsl_save_metadata_if_changed(AvbABOps* ab_ops,
- AvbABData* ab_data,
- AvbABData* ab_data_orig) {
- if (avb_safe_memcmp(ab_data, ab_data_orig, sizeof(AvbABData)) != 0) {
- avb_debug("Writing A/B metadata to disk.\n");
- return ab_ops->write_ab_metadata(ab_ops, ab_data);
- }
- return AVB_IO_RESULT_OK;
-}
-
-/* Helper function to load metadata - returns AVB_IO_RESULT_OK on
- * success, error code otherwise. This is a copy of load_metadata()
- * from /lib/avb/libavb_ab/avb_ab_flow.c.
- */
-static AvbIOResult fsl_load_metadata(AvbABOps* ab_ops,
- AvbABData* ab_data,
- AvbABData* ab_data_orig) {
- AvbIOResult io_ret;
-
- io_ret = ab_ops->read_ab_metadata(ab_ops, ab_data);
- if (io_ret != AVB_IO_RESULT_OK) {
- avb_error("I/O error while loading A/B metadata.\n");
- return io_ret;
- }
- *ab_data_orig = *ab_data;
-
- /* Ensure data is normalized, e.g. illegal states will be marked as
- * unbootable and all unbootable states are represented with
- * (priority=0, tries_remaining=0, successful_boot=0).
- */
- fsl_slot_normalize(&ab_data->slots[0]);
- fsl_slot_normalize(&ab_data->slots[1]);
- return AVB_IO_RESULT_OK;
-}
-
#ifdef CONFIG_DUAL_BOOTLOADER
+// dual bootloader flow in uboot proper
AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
const char* const* requested_partitions,
AvbSlotVerifyFlags flags,
@@ -576,7 +861,7 @@ AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
AvbSlotVerifyData* slot_data = NULL;
AvbSlotVerifyData* data = NULL;
AvbABFlowResult ret;
- AvbABData ab_data, ab_data_orig;
+ struct bootloader_control ab_data, ab_data_orig;
AvbIOResult io_ret;
bool saw_and_allowed_verification_error = false;
AvbSlotVerifyResult verify_result;
@@ -602,12 +887,12 @@ AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
goto out;
}
/* Clear the bootloader_verified flag. */
- ab_data.slots[target_slot].bootloader_verified = 0;
+ ab_data.slot_info[target_slot].bootloader_verified = 0;
- printf("Verifying slot %s ...\n", slot_suffixes[target_slot]);
+ printf("Verifying slot %s ...\n", slot_suffix[target_slot]);
verify_result = avb_slot_verify(ops,
requested_partitions,
- slot_suffixes[target_slot],
+ slot_suffix[target_slot],
flags,
hashtree_error_mode,
&slot_data);
@@ -639,7 +924,7 @@ AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
/* Do nothing since we allow this. */
avb_debugv("Allowing slot ",
- slot_suffixes[target_slot],
+ slot_suffix[target_slot],
" which verified "
"with result ",
avb_slot_verify_result_to_string(verify_result),
@@ -667,16 +952,16 @@ AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
* slot been marked as "unbootable" due to some random failures (like
* eMMC/DRAM access error at some critical temperature).
*/
- if (ab_data.slots[target_slot].successful_boot)
+ if (ab_data.slot_info[target_slot].successful_boot)
do_reset(NULL, 0, 0, NULL);
else {
avb_errorv("Error verifying slot ",
- slot_suffixes[target_slot],
+ slot_suffix[target_slot],
" with result ",
avb_slot_verify_result_to_string(verify_result),
" - setting unbootable.\n",
NULL);
- fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
+ fsl_slot_set_unbootable(&ab_data.slot_info[target_slot]);
/* Only the slot chosen by SPL will be verified here so we
* return AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS if the
@@ -690,7 +975,7 @@ AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
/* Update stored rollback index only when the slot has been marked
* as successful. Do this for every rollback index location.
*/
- if (ab_data.slots[target_slot].successful_boot != 0) {
+ if (ab_data.slot_info[target_slot].successful_boot != 0) {
for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
rollback_index_value = slot_data->rollback_indexes[n];
@@ -702,7 +987,7 @@ AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
goto out;
} else if (io_ret != AVB_IO_RESULT_OK) {
- avb_error("Error getting rollback index for slot.\n");
+ printf("Error getting rollback index for slot.\n");
ret = AVB_AB_FLOW_RESULT_ERROR_IO;
goto out;
}
@@ -713,7 +998,7 @@ AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
goto out;
} else if (io_ret != AVB_IO_RESULT_OK) {
- avb_error("Error setting stored rollback index.\n");
+ printf("Error setting stored rollback index.\n");
ret = AVB_AB_FLOW_RESULT_ERROR_IO;
goto out;
}
@@ -770,7 +1055,7 @@ bool is_spl_recovery(void)
}
void check_spl_recovery(void)
{
- AvbABData ab_data, ab_data_orig;
+ struct bootloader_control ab_data, ab_data_orig;
AvbIOResult io_ret;
io_ret = fsl_load_metadata(&fsl_avb_ab_ops, &ab_data, &ab_data_orig);
@@ -844,7 +1129,7 @@ AvbABFlowResult avb_single_flow(AvbABOps* ab_ops,
if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
/* Do nothing since we allow this. */
avb_debugv("Allowing slot ",
- slot_suffixes[n],
+ slot_suffix[n],
" which verified "
"with result ",
avb_slot_verify_result_to_string(verify_result),
@@ -900,7 +1185,7 @@ AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
AvbSlotVerifyData* slot_data[2] = {NULL, NULL};
AvbSlotVerifyData* data = NULL;
AvbABFlowResult ret;
- AvbABData ab_data, ab_data_orig;
+ struct bootloader_control ab_data, ab_data_orig;
size_t slot_index_to_boot, n;
AvbIOResult io_ret;
bool saw_and_allowed_verification_error = false;
@@ -921,16 +1206,16 @@ AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
slot_index_to_boot = 2; // Means not 0 or 1
target_slot =
- (ab_data.slots[1].priority > ab_data.slots[0].priority) ? 1 : 0;
+ (ab_data.slot_info[1].priority > ab_data.slot_info[0].priority) ? 1 : 0;
for (n = 0; n < 2; n++) {
- if (!fsl_slot_is_bootable(&ab_data.slots[target_slot])) {
+ if (!fsl_slot_is_bootable(&ab_data.slot_info[target_slot])) {
target_slot = (target_slot == 1 ? 0 : 1);
continue;
}
verify_result = avb_slot_verify(ops,
requested_partitions,
- slot_suffixes[target_slot],
+ slot_suffix[target_slot],
flags,
hashtree_error_mode,
&slot_data[target_slot]);
@@ -963,7 +1248,7 @@ AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
/* Do nothing since we allow this. */
avb_debugv("Allowing slot ",
- slot_suffixes[target_slot],
+ slot_suffix[target_slot],
" which verified "
"with result ",
avb_slot_verify_result_to_string(verify_result),
@@ -993,16 +1278,16 @@ AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
* slot been marked as "unbootable" due to some random failures (like
* eMMC/DRAM access error at some critical temperature).
*/
- if (ab_data.slots[target_slot].successful_boot)
+ if (ab_data.slot_info[target_slot].successful_boot)
do_reset(NULL, 0, 0, NULL);
else {
avb_errorv("Error verifying slot ",
- slot_suffixes[target_slot],
+ slot_suffix[target_slot],
" with result ",
avb_slot_verify_result_to_string(verify_result),
" - setting unbootable.\n",
NULL);
- fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
+ fsl_slot_set_unbootable(&ab_data.slot_info[target_slot]);
set_slot_unbootable = false;
}
if (slot_data[target_slot] != NULL) {
@@ -1016,7 +1301,7 @@ AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
if (slot_index_to_boot == 2) {
/* No bootable slots! */
- avb_error("No bootable slots found.\n");
+ printf("No bootable slots found.\n");
ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
goto out;
}
@@ -1024,7 +1309,7 @@ AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
/* Update stored rollback index only when the slot has been marked
* as successful. Do this for every rollback index location.
*/
- if (ab_data.slots[slot_index_to_boot].successful_boot != 0) {
+ if (ab_data.slot_info[slot_index_to_boot].successful_boot != 0) {
for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
rollback_index_value = slot_data[slot_index_to_boot]->rollback_indexes[n];
@@ -1036,7 +1321,7 @@ AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
goto out;
} else if (io_ret != AVB_IO_RESULT_OK) {
- avb_error("Error getting rollback index for slot.\n");
+ printf("Error getting rollback index for slot.\n");
ret = AVB_AB_FLOW_RESULT_ERROR_IO;
goto out;
}
@@ -1047,7 +1332,7 @@ AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
goto out;
} else if (io_ret != AVB_IO_RESULT_OK) {
- avb_error("Error setting stored rollback index.\n");
+ printf("Error setting stored rollback index.\n");
ret = AVB_AB_FLOW_RESULT_ERROR_IO;
goto out;
}
@@ -1069,9 +1354,9 @@ AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
}
/* ... and decrement tries remaining, if applicable. */
- if (!ab_data.slots[slot_index_to_boot].successful_boot &&
- (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) {
- ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
+ if (!ab_data.slot_info[slot_index_to_boot].successful_boot &&
+ (ab_data.slot_info[slot_index_to_boot].tries_remaining > 0)) {
+ ab_data.slot_info[slot_index_to_boot].tries_remaining -= 1;
}
out:
@@ -1105,5 +1390,4 @@ out:
return ret;
}
#endif /* CONFIG_DUAL_BOOTLOADER */
-
#endif /* CONFIG_DUAL_BOOTLOADER && CONFIG_SPL_BUILD */
diff --git a/lib/avb/fsl/fsl_bootctrl.h b/lib/avb/fsl/fsl_bootctrl.h
new file mode 100644
index 0000000000..2d5be97f6b
--- /dev/null
+++ b/lib/avb/fsl/fsl_bootctrl.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2020 NXP
+ *
+ */
+
+#ifndef __FSL_BOOTCTRL_H__
+#define __FSL_BOOTCTRL_H__
+
+#include "android_bootloader_message.h"
+
+typedef enum {
+ AVB_AB_FLOW_RESULT_OK,
+ AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR,
+ AVB_AB_FLOW_RESULT_ERROR_OOM,
+ AVB_AB_FLOW_RESULT_ERROR_IO,
+ AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
+ AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT
+} AvbABFlowResult;
+
+/* High-level operations/functions/methods for A/B that are platform
+ * dependent.
+ */
+struct AvbABOps;
+typedef struct AvbABOps AvbABOps;
+
+struct AvbABOps {
+ /* Operations from libavb. */
+ AvbOps* ops;
+
+ /* Reads A/B metadata from persistent storage. Returned data is
+ * properly byteswapped. Returns AVB_IO_RESULT_OK on success, error
+ * code otherwise.
+ *
+ * If the data read is invalid (e.g. wrong magic or CRC checksum
+ * failure), the metadata shoule be reset using fsl_avb_ab_data_init()
+ * and then written to persistent storage.
+ *
+ * Implementations will typically want to use fsl_avb_ab_data_read()
+ * here to use the 'misc' partition for persistent storage.
+ */
+ AvbIOResult (*read_ab_metadata)(AvbABOps* ab_ops, struct bootloader_control* data);
+
+ /* Writes A/B metadata to persistent storage. This will byteswap and
+ * update the CRC as needed. Returns AVB_IO_RESULT_OK on success,
+ * error code otherwise.
+ *
+ * Implementations will typically want to use fsl_avb_ab_data_write()
+ * here to use the 'misc' partition for persistent storage.
+ */
+ AvbIOResult (*write_ab_metadata)(AvbABOps* ab_ops,
+ const struct bootloader_control* data);
+};
+
+/* Copies |src| to |dest|, byte-swapping fields in the
+ * process. Returns false if the data is invalid (e.g. wrong magic,
+ * wrong CRC32 etc.), true otherwise.
+ */
+bool fsl_avb_ab_data_verify_and_byteswap(const struct bootloader_control* src,
+ struct bootloader_control* dest);
+
+/* Copies |src| to |dest|, byte-swapping fields in the process. Also
+ * updates the |crc32| field in |dest|.
+ */
+void fsl_avb_ab_data_update_crc_and_byteswap(const struct bootloader_control* src,
+ struct bootloader_control* dest);
+
+/* Initializes |data| such that it has two slots and both slots have
+ * maximum tries remaining. The CRC is not set.
+ */
+void fsl_avb_ab_data_init(struct bootloader_control* data);
+
+/* Reads A/B metadata from the 'misc' partition using |ops|. Returned
+ * data is properly byteswapped. Returns AVB_IO_RESULT_OK on
+ * success, error code otherwise.
+ *
+ * If the data read from disk is invalid (e.g. wrong magic or CRC
+ * checksum failure), the metadata will be reset using
+ * fsl_avb_ab_data_init() and then written to disk.
+ */
+AvbIOResult fsl_avb_ab_data_read(AvbABOps* ab_ops, struct bootloader_control* data);
+
+/* Writes A/B metadata to the 'misc' partition using |ops|. This will
+ * byteswap and update the CRC as needed. Returns AVB_IO_RESULT_OK on
+ * success, error code otherwise.
+ */
+AvbIOResult fsl_avb_ab_data_write(AvbABOps* ab_ops, const struct bootloader_control* data);
+
+/* True if the given slot is active, false otherwise.
+ * */
+bool fsl_slot_is_bootable(struct slot_metadata* slot);
+
+/* Mark one slot as active. */
+AvbIOResult fsl_avb_ab_mark_slot_active(AvbABOps* ab_ops,
+ unsigned int slot_number);
+
+/* This is the fast version of avb_ab_flow(), this function will
+ * not check another slot if one slot can pass the verify (or verify
+ * fail is acceptable).
+ */
+AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
+ const char* const* requested_partitions,
+ AvbSlotVerifyFlags flags,
+ AvbHashtreeErrorMode hashtree_error_mode,
+ AvbSlotVerifyData** out_data);
+
+/* This is for legacy i.mx6/7 which don't enable A/B but want to
+ * verify boot/recovery with AVB */
+AvbABFlowResult avb_single_flow(AvbABOps* ab_ops,
+ const char* const* requested_partitions,
+ AvbSlotVerifyFlags flags,
+ AvbHashtreeErrorMode hashtree_error_mode,
+ AvbSlotVerifyData** out_data);
+
+/* Avb verify flow for dual bootloader, only the slot chosen by SPL will
+ * be verified.
+ */
+AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
+ const char* const* requested_partitions,
+ AvbSlotVerifyFlags flags,
+ AvbHashtreeErrorMode hashtree_error_mode,
+ AvbSlotVerifyData** out_data);
+
+/* check if the fastboot getvar cmd is for query [avb] bootctl's slot var
+ * cmd is the fastboot getvar's cmd in
+ * return true if it is a bootctl related cmd, false if it's not.
+ * */
+bool is_slotvar_avb(char *cmd);
+
+/* Get current bootable slot with higher priority.
+ * return 0 for the first slot
+ * return 1 for the second slot
+ * return -1 for not supported slot
+ * */
+int get_curr_slot(struct bootloader_control* ab_data);
+
+/* return 0 for the first slot
+ * return 1 for the second slot
+ * return -1 for not supported slot
+ * */
+int slotidx_from_suffix(char *suffix);
+
+/* return fastboot's getvar cmd response
+ * cmd is the fastboot getvar's cmd in
+ * if return 0, buffer is bootctl's slot var out
+ * if return -1, buffer is error string
+ * */
+
+/* read a/b metadata to get curr slot
+ * return slot suffix '_a'/'_b' or NULL */
+char *select_slot(AvbABOps *ab_ops);
+
+int get_slotvar_avb(AvbABOps *ab_ops, char *cmd, char *buffer, size_t size);
+
+#endif /* __FSL_BOOTCTRL_H__ */
diff --git a/lib/avb/libavb_ab/Makefile b/lib/avb/libavb_ab/Makefile
deleted file mode 100644
index f22d0ed83f..0000000000
--- a/lib/avb/libavb_ab/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-ccflags-y += -DAVB_COMPILATION
-obj-y += avb_ab_flow.o
diff --git a/lib/avb/libavb_ab/avb_ab_flow.c b/lib/avb/libavb_ab/avb_ab_flow.c
deleted file mode 100644
index 6097988b19..0000000000
--- a/lib/avb/libavb_ab/avb_ab_flow.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "avb_ab_flow.h"
-
-bool avb_ab_data_verify_and_byteswap(const AvbABData* src, AvbABData* dest) {
- /* Ensure magic is correct. */
- if (avb_safe_memcmp(src->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN) != 0) {
- avb_error("Magic is incorrect.\n");
- return false;
- }
-
- avb_memcpy(dest, src, sizeof(AvbABData));
- dest->crc32 = avb_be32toh(dest->crc32);
-
- /* Ensure we don't attempt to access any fields if the major version
- * is not supported.
- */
- if (dest->version_major > AVB_AB_MAJOR_VERSION) {
- avb_error("No support for given major version.\n");
- return false;
- }
-
- /* Bail if CRC32 doesn't match. */
- if (dest->crc32 !=
- avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t))) {
- avb_error("CRC32 does not match.\n");
- return false;
- }
-
- return true;
-}
-
-void avb_ab_data_update_crc_and_byteswap(const AvbABData* src,
- AvbABData* dest) {
- avb_memcpy(dest, src, sizeof(AvbABData));
- dest->crc32 = avb_htobe32(
- avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t)));
-}
-
-void avb_ab_data_init(AvbABData* data) {
- avb_memset(data, '\0', sizeof(AvbABData));
- avb_memcpy(data->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN);
- data->version_major = AVB_AB_MAJOR_VERSION;
- data->version_minor = AVB_AB_MINOR_VERSION;
- data->slots[0].priority = AVB_AB_MAX_PRIORITY;
- data->slots[0].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
- data->slots[0].successful_boot = 0;
-#ifdef CONFIG_DUAL_BOOTLOADER
- data->slots[0].bootloader_verified = 0;
-#endif
- data->slots[1].priority = AVB_AB_MAX_PRIORITY - 1;
- data->slots[1].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
- data->slots[1].successful_boot = 0;
-#ifdef CONFIG_DUAL_BOOTLOADER
- data->slots[1].bootloader_verified = 0;
-#endif
-}
-
-/* The AvbABData struct is stored 2048 bytes into the 'misc' partition
- * following the 'struct bootloader_message' field. The struct is
- * compatible with the guidelines in bootable/recovery/bootloader.h -
- * e.g. it is stored in the |slot_suffix| field, starts with a
- * NUL-byte, and is 32 bytes long.
- */
-#define AB_METADATA_MISC_PARTITION_OFFSET 2048
-
-AvbIOResult avb_ab_data_read(AvbABOps* ab_ops, AvbABData* data) {
- AvbOps* ops = ab_ops->ops;
- AvbABData serialized;
- AvbIOResult io_ret;
- size_t num_bytes_read;
-
- io_ret = ops->read_from_partition(ops,
- "misc",
- AB_METADATA_MISC_PARTITION_OFFSET,
- sizeof(AvbABData),
- &serialized,
- &num_bytes_read);
- if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
- return AVB_IO_RESULT_ERROR_OOM;
- } else if (io_ret != AVB_IO_RESULT_OK ||
- num_bytes_read != sizeof(AvbABData)) {
- avb_error("Error reading A/B metadata.\n");
- return AVB_IO_RESULT_ERROR_IO;
- }
-
- if (!avb_ab_data_verify_and_byteswap(&serialized, data)) {
- avb_error(
- "Error validating A/B metadata from disk. "
- "Resetting and writing new A/B metadata to disk.\n");
- avb_ab_data_init(data);
- return avb_ab_data_write(ab_ops, data);
- }
-
- return AVB_IO_RESULT_OK;
-}
-
-AvbIOResult avb_ab_data_write(AvbABOps* ab_ops, const AvbABData* data) {
- AvbOps* ops = ab_ops->ops;
- AvbABData serialized;
- AvbIOResult io_ret;
-
- avb_ab_data_update_crc_and_byteswap(data, &serialized);
- io_ret = ops->write_to_partition(ops,
- "misc",
- AB_METADATA_MISC_PARTITION_OFFSET,
- sizeof(AvbABData),
- &serialized);
- if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
- return AVB_IO_RESULT_ERROR_OOM;
- } else if (io_ret != AVB_IO_RESULT_OK) {
- avb_error("Error writing A/B metadata.\n");
- return AVB_IO_RESULT_ERROR_IO;
- }
- return AVB_IO_RESULT_OK;
-}
-
-static bool slot_is_bootable(AvbABSlotData* slot) {
- return slot->priority > 0 &&
- (slot->successful_boot || (slot->tries_remaining > 0));
-}
-
-static void slot_set_unbootable(AvbABSlotData* slot) {
- slot->priority = 0;
- slot->tries_remaining = 0;
- slot->successful_boot = 0;
-}
-
-/* Ensure all unbootable and/or illegal states are marked as the
- * canonical 'unbootable' state, e.g. priority=0, tries_remaining=0,
- * and successful_boot=0.
- */
-static void slot_normalize(AvbABSlotData* slot) {
- if (slot->priority > 0) {
- if (slot->tries_remaining == 0 && !slot->successful_boot) {
- /* We've exhausted all tries -> unbootable. */
- slot_set_unbootable(slot);
- }
- if (slot->tries_remaining > 0 && slot->successful_boot) {
- /* Illegal state - avb_ab_mark_slot_successful() will clear
- * tries_remaining when setting successful_boot.
- */
- slot_set_unbootable(slot);
- }
- } else {
- slot_set_unbootable(slot);
- }
-}
-
-static const char* slot_suffixes[2] = {"_a", "_b"};
-
-/* Helper function to load metadata - returns AVB_IO_RESULT_OK on
- * success, error code otherwise.
- */
-static AvbIOResult load_metadata(AvbABOps* ab_ops,
- AvbABData* ab_data,
- AvbABData* ab_data_orig) {
- AvbIOResult io_ret;
-
- io_ret = ab_ops->read_ab_metadata(ab_ops, ab_data);
- if (io_ret != AVB_IO_RESULT_OK) {
- avb_error("I/O error while loading A/B metadata.\n");
- return io_ret;
- }
- *ab_data_orig = *ab_data;
-
- /* Ensure data is normalized, e.g. illegal states will be marked as
- * unbootable and all unbootable states are represented with
- * (priority=0, tries_remaining=0, successful_boot=0).
- */
- slot_normalize(&ab_data->slots[0]);
- slot_normalize(&ab_data->slots[1]);
- return AVB_IO_RESULT_OK;
-}
-
-/* Writes A/B metadata to disk only if it has changed - returns
- * AVB_IO_RESULT_OK on success, error code otherwise.
- */
-static AvbIOResult save_metadata_if_changed(AvbABOps* ab_ops,
- AvbABData* ab_data,
- AvbABData* ab_data_orig) {
- if (avb_safe_memcmp(ab_data, ab_data_orig, sizeof(AvbABData)) != 0) {
- avb_debug("Writing A/B metadata to disk.\n");
- return ab_ops->write_ab_metadata(ab_ops, ab_data);
- }
- return AVB_IO_RESULT_OK;
-}
-
-AvbABFlowResult avb_ab_flow(AvbABOps* ab_ops,
- const char* const* requested_partitions,
- AvbSlotVerifyFlags flags,
- AvbHashtreeErrorMode hashtree_error_mode,
- AvbSlotVerifyData** out_data) {
- AvbOps* ops = ab_ops->ops;
- AvbSlotVerifyData* slot_data[2] = {NULL, NULL};
- AvbSlotVerifyData* data = NULL;
- AvbABFlowResult ret;
- AvbABData ab_data, ab_data_orig;
- size_t slot_index_to_boot, n;
- AvbIOResult io_ret;
- bool saw_and_allowed_verification_error = false;
-
- io_ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
- if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
- ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
- goto out;
- } else if (io_ret != AVB_IO_RESULT_OK) {
- ret = AVB_AB_FLOW_RESULT_ERROR_IO;
- goto out;
- }
-
- /* Validate all bootable slots. */
- for (n = 0; n < 2; n++) {
- if (slot_is_bootable(&ab_data.slots[n])) {
- AvbSlotVerifyResult verify_result;
- bool set_slot_unbootable = false;
-
- verify_result = avb_slot_verify(ops,
- requested_partitions,
- slot_suffixes[n],
- flags,
- hashtree_error_mode,
- &slot_data[n]);
- switch (verify_result) {
- case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
- ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
- goto out;
-
- case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
- ret = AVB_AB_FLOW_RESULT_ERROR_IO;
- goto out;
-
- case AVB_SLOT_VERIFY_RESULT_OK:
- break;
-
- case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
- case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
- /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
- * these mean game over.
- */
- set_slot_unbootable = true;
- break;
-
- /* explicit fallthrough. */
- case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
- case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
- case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
- if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
- /* Do nothing since we allow this. */
- avb_debugv("Allowing slot ",
- slot_suffixes[n],
- " which verified "
- "with result ",
- avb_slot_verify_result_to_string(verify_result),
- " because "
- "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
- "is set.\n",
- NULL);
- saw_and_allowed_verification_error = true;
- } else {
- set_slot_unbootable = true;
- }
- break;
-
- case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
- ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
- goto out;
- /* Do not add a 'default:' case here because of -Wswitch. */
- }
-
- if (set_slot_unbootable) {
- avb_errorv("Error verifying slot ",
- slot_suffixes[n],
- " with result ",
- avb_slot_verify_result_to_string(verify_result),
- " - setting unbootable.\n",
- NULL);
- slot_set_unbootable(&ab_data.slots[n]);
- }
- }
- }
-
- if (slot_is_bootable(&ab_data.slots[0]) &&
- slot_is_bootable(&ab_data.slots[1])) {
- if (ab_data.slots[1].priority > ab_data.slots[0].priority) {
- slot_index_to_boot = 1;
- } else {
- slot_index_to_boot = 0;
- }
- } else if (slot_is_bootable(&ab_data.slots[0])) {
- slot_index_to_boot = 0;
- } else if (slot_is_bootable(&ab_data.slots[1])) {
- slot_index_to_boot = 1;
- } else {
- /* No bootable slots! */
- avb_error("No bootable slots found.\n");
- ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
- goto out;
- }
-
- /* Update stored rollback index such that the stored rollback index
- * is the largest value supporting all currently bootable slots. Do
- * this for every rollback index location.
- */
- for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
- uint64_t rollback_index_value = 0;
-
- if (slot_data[0] != NULL && slot_data[1] != NULL) {
- uint64_t a_rollback_index = slot_data[0]->rollback_indexes[n];
- uint64_t b_rollback_index = slot_data[1]->rollback_indexes[n];
- rollback_index_value =
- (a_rollback_index < b_rollback_index ? a_rollback_index
- : b_rollback_index);
- } else if (slot_data[0] != NULL) {
- rollback_index_value = slot_data[0]->rollback_indexes[n];
- } else if (slot_data[1] != NULL) {
- rollback_index_value = slot_data[1]->rollback_indexes[n];
- }
-
- if (rollback_index_value != 0) {
- uint64_t current_rollback_index_value;
- io_ret = ops->read_rollback_index(ops, n, &current_rollback_index_value);
- if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
- ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
- goto out;
- } else if (io_ret != AVB_IO_RESULT_OK) {
- avb_error("Error getting rollback index for slot.\n");
- ret = AVB_AB_FLOW_RESULT_ERROR_IO;
- goto out;
- }
- if (current_rollback_index_value != rollback_index_value) {
- io_ret = ops->write_rollback_index(ops, n, rollback_index_value);
- if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
- ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
- goto out;
- } else if (io_ret != AVB_IO_RESULT_OK) {
- avb_error("Error setting stored rollback index.\n");
- ret = AVB_AB_FLOW_RESULT_ERROR_IO;
- goto out;
- }
- }
- }
- }
-
- /* Finally, select this slot. */
- avb_assert(slot_data[slot_index_to_boot] != NULL);
- data = slot_data[slot_index_to_boot];
- slot_data[slot_index_to_boot] = NULL;
- if (saw_and_allowed_verification_error) {
- avb_assert(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
- ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
- } else {
- ret = AVB_AB_FLOW_RESULT_OK;
- }
-
- /* ... and decrement tries remaining, if applicable. */
- if (!ab_data.slots[slot_index_to_boot].successful_boot &&
- ab_data.slots[slot_index_to_boot].tries_remaining > 0) {
- ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
- }
-
-out:
- io_ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
- if (io_ret != AVB_IO_RESULT_OK) {
- if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
- ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
- } else {
- ret = AVB_AB_FLOW_RESULT_ERROR_IO;
- }
- if (data != NULL) {
- avb_slot_verify_data_free(data);
- data = NULL;
- }
- }
-
- for (n = 0; n < 2; n++) {
- if (slot_data[n] != NULL) {
- avb_slot_verify_data_free(slot_data[n]);
- }
- }
-
- if (out_data != NULL) {
- *out_data = data;
- } else {
- if (data != NULL) {
- avb_slot_verify_data_free(data);
- }
- }
-
- return ret;
-}
-
-AvbIOResult avb_ab_mark_slot_active(AvbABOps* ab_ops,
- unsigned int slot_number) {
- AvbABData ab_data, ab_data_orig;
- unsigned int other_slot_number;
- AvbIOResult ret;
-
- avb_assert(slot_number < 2);
-
- ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
- if (ret != AVB_IO_RESULT_OK) {
- goto out;
- }
-
- /* Make requested slot top priority, unsuccessful, and with max tries. */
- ab_data.slots[slot_number].priority = AVB_AB_MAX_PRIORITY;
- ab_data.slots[slot_number].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
- ab_data.slots[slot_number].successful_boot = 0;
-#ifdef CONFIG_DUAL_BOOTLOADER
- ab_data.slots[slot_number].bootloader_verified = 0;
-#endif
-
- /* Ensure other slot doesn't have as high a priority. */
- other_slot_number = 1 - slot_number;
- if (ab_data.slots[other_slot_number].priority == AVB_AB_MAX_PRIORITY) {
- ab_data.slots[other_slot_number].priority = AVB_AB_MAX_PRIORITY - 1;
- }
-
- ret = AVB_IO_RESULT_OK;
-
-out:
- if (ret == AVB_IO_RESULT_OK) {
- ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
- }
- return ret;
-}
-
-AvbIOResult avb_ab_mark_slot_unbootable(AvbABOps* ab_ops,
- unsigned int slot_number) {
- AvbABData ab_data, ab_data_orig;
- AvbIOResult ret;
-
- avb_assert(slot_number < 2);
-
- ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
- if (ret != AVB_IO_RESULT_OK) {
- goto out;
- }
-
- slot_set_unbootable(&ab_data.slots[slot_number]);
-
- ret = AVB_IO_RESULT_OK;
-
-out:
- if (ret == AVB_IO_RESULT_OK) {
- ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
- }
- return ret;
-}
-
-AvbIOResult avb_ab_mark_slot_successful(AvbABOps* ab_ops,
- unsigned int slot_number) {
- AvbABData ab_data, ab_data_orig;
- AvbIOResult ret;
-
- avb_assert(slot_number < 2);
-
- ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
- if (ret != AVB_IO_RESULT_OK) {
- goto out;
- }
-
- if (!slot_is_bootable(&ab_data.slots[slot_number])) {
- avb_error("Cannot mark unbootable slot as successful.\n");
- ret = AVB_IO_RESULT_OK;
- goto out;
- }
-
- ab_data.slots[slot_number].tries_remaining = 0;
- ab_data.slots[slot_number].successful_boot = 1;
-
- ret = AVB_IO_RESULT_OK;
-
-out:
- if (ret == AVB_IO_RESULT_OK) {
- ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
- }
- return ret;
-}
-
-const char* avb_ab_flow_result_to_string(AvbABFlowResult result) {
- const char* ret = NULL;
-
- switch (result) {
- case AVB_AB_FLOW_RESULT_OK:
- ret = "OK";
- break;
-
- case AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR:
- ret = "OK_WITH_VERIFICATION_ERROR";
- break;
-
- case AVB_AB_FLOW_RESULT_ERROR_OOM:
- ret = "ERROR_OOM";
- break;
-
- case AVB_AB_FLOW_RESULT_ERROR_IO:
- ret = "ERROR_IO";
- break;
-
- case AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS:
- ret = "ERROR_NO_BOOTABLE_SLOTS";
- break;
-
- case AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT:
- ret = "ERROR_INVALID_ARGUMENT";
- break;
- /* Do not add a 'default:' case here because of -Wswitch. */
- }
-
- if (ret == NULL) {
- avb_error("Unknown AvbABFlowResult value.\n");
- ret = "(unknown)";
- }
-
- return ret;
-}
diff --git a/lib/avb/libavb_ab/avb_ab_flow.h b/lib/avb/libavb_ab/avb_ab_flow.h
deleted file mode 100644
index 1e09d398f2..0000000000
--- a/lib/avb/libavb_ab/avb_ab_flow.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#if !defined(AVB_INSIDE_LIBAVB_AB_H) && !defined(AVB_COMPILATION)
-#error \
- "Never include this file directly, include libavb_ab/libavb_ab.h instead."
-#endif
-
-#ifndef AVB_AB_FLOW_H_
-#define AVB_AB_FLOW_H_
-
-#include "avb_ab_ops.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Magic for the A/B struct when serialized. */
-#define AVB_AB_MAGIC "\0AB0"
-#define AVB_AB_MAGIC_LEN 4
-
-/* Versioning for the on-disk A/B metadata - keep in sync with avbtool. */
-#define AVB_AB_MAJOR_VERSION 1
-#define AVB_AB_MINOR_VERSION 0
-
-/* Size of AvbABData struct. */
-#define AVB_AB_DATA_SIZE 32
-
-/* Maximum values for slot data */
-#define AVB_AB_MAX_PRIORITY 15
-#define AVB_AB_MAX_TRIES_REMAINING 7
-
-/* Struct used for recording per-slot metadata.
- *
- * When serialized, data is stored in network byte-order.
- */
-typedef struct AvbABSlotData {
- /* Slot priority. Valid values range from 0 to AVB_AB_MAX_PRIORITY,
- * both inclusive with 1 being the lowest and AVB_AB_MAX_PRIORITY
- * being the highest. The special value 0 is used to indicate the
- * slot is unbootable.
- */
- uint8_t priority;
-
- /* Number of times left attempting to boot this slot ranging from 0
- * to AVB_AB_MAX_TRIES_REMAINING.
- */
- uint8_t tries_remaining;
-
- /* Non-zero if this slot has booted successfully, 0 otherwise. */
- uint8_t successful_boot;
-
- /* Reserved for future use. */
- uint8_t bootloader_verified;
-} AVB_ATTR_PACKED AvbABSlotData;
-
-/* Struct used for recording A/B metadata.
- *
- * When serialized, data is stored in network byte-order.
- */
-typedef struct AvbABData {
- /* Magic number used for identification - see AVB_AB_MAGIC. */
- uint8_t magic[AVB_AB_MAGIC_LEN];
-
- /* Version of on-disk struct - see AVB_AB_{MAJOR,MINOR}_VERSION. */
- uint8_t version_major;
- uint8_t version_minor;
-
- /* Padding to ensure |slots| field start eight bytes in. */
- uint8_t reserved1[2];
-
- /* Per-slot metadata. */
- AvbABSlotData slots[2];
-
- /* Last boot slot */
- uint8_t last_boot;
-
- /* spl recovery mode */
- bool spl_recovery;
-
- /* Reserved for future use. */
- uint8_t reserved2[10];
-
- /* CRC32 of all 28 bytes preceding this field. */
- uint32_t crc32;
-} AVB_ATTR_PACKED AvbABData;
-
-/* Copies |src| to |dest|, byte-swapping fields in the
- * process. Returns false if the data is invalid (e.g. wrong magic,
- * wrong CRC32 etc.), true otherwise.
- */
-bool avb_ab_data_verify_and_byteswap(const AvbABData* src, AvbABData* dest);
-
-/* Copies |src| to |dest|, byte-swapping fields in the process. Also
- * updates the |crc32| field in |dest|.
- */
-void avb_ab_data_update_crc_and_byteswap(const AvbABData* src, AvbABData* dest);
-
-/* Initializes |data| such that it has two slots and both slots have
- * maximum tries remaining. The CRC is not set.
- */
-void avb_ab_data_init(AvbABData* data);
-
-/* Reads A/B metadata from the 'misc' partition using |ops|. Returned
- * data is properly byteswapped. Returns AVB_IO_RESULT_OK on
- * success, error code otherwise.
- *
- * If the data read from disk is invalid (e.g. wrong magic or CRC
- * checksum failure), the metadata will be reset using
- * avb_ab_data_init() and then written to disk.
- */
-AvbIOResult avb_ab_data_read(AvbABOps* ab_ops, AvbABData* data);
-
-/* Writes A/B metadata to the 'misc' partition using |ops|. This will
- * byteswap and update the CRC as needed. Returns AVB_IO_RESULT_OK on
- * success, error code otherwise.
- */
-AvbIOResult avb_ab_data_write(AvbABOps* ab_ops, const AvbABData* data);
-
-/* Return codes used in avb_ab_flow(), see that function for
- * documentation of each value.
- */
-typedef enum {
- AVB_AB_FLOW_RESULT_OK,
- AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR,
- AVB_AB_FLOW_RESULT_ERROR_OOM,
- AVB_AB_FLOW_RESULT_ERROR_IO,
- AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
- AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT
-} AvbABFlowResult;
-
-/* Get a textual representation of |result|. */
-const char* avb_ab_flow_result_to_string(AvbABFlowResult result);
-
-/* High-level function to select a slot to boot. The following
- * algorithm is used:
- *
- * 1. A/B metadata is loaded and validated using the
- * read_ab_metadata() operation. Typically this means it's read from
- * the 'misc' partition and if it's invalid then it's reset using
- * avb_ab_data_init() and this reset metadata is returned.
- *
- * 2. All bootable slots listed in the A/B metadata are verified using
- * avb_slot_verify(). If a slot is invalid or if it fails verification
- * (and AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is not set, see
- * below), it will be marked as unbootable in the A/B metadata and the
- * metadata will be saved to disk before returning.
- *
- * 3. If there are no bootable slots, the value
- * AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS is returned.
- *
- * 4. For each bootable slot, the Stored Rollback Indexes are updated
- * such that for each rollback index location, the Stored Rollback
- * Index is the largest number smaller than or equal to the Rollback
- * Index of each slot.
- *
- * 5. The bootable slot with the highest priority is selected and
- * returned in |out_data|. If this slot is already marked as
- * successful, the A/B metadata is not modified. However, if the slot
- * is not marked as bootable its |tries_remaining| count is
- * decremented and the A/B metadata is saved to disk before returning.
- * In either case the value AVB_AB_FLOW_RESULT_OK is returning.
- *
- * The partitions to load is given in |requested_partitions| as a
- * NULL-terminated array of NUL-terminated strings. Typically the
- * |requested_partitions| array only contains a single item for the
- * boot partition, 'boot'.
- *
- * If the device is unlocked (and _only_ if it's unlocked), the
- * AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR flag should be set
- * in the |flags| parameter. This will allow considering slots as
- * verified even when avb_slot_verify() returns
- * AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
- * AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION, or
- * AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX for the slot in
- * question.
- *
- * Note that neither androidboot.slot_suffix nor androidboot.slot are
- * set in the |cmdline| field in |AvbSlotVerifyData| - you will have
- * to pass these yourself.
- *
- * If a slot was selected and it verified then AVB_AB_FLOW_RESULT_OK
- * is returned.
- *
- * If a slot was selected but it didn't verify then
- * AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR is returned. This can
- * only happen when the AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
- * flag is set.
- *
- * If an I/O operation - such as loading/saving metadata or checking
- * rollback indexes - fail, the value AVB_AB_FLOW_RESULT_ERROR_IO is
- * returned.
- *
- * If memory allocation fails, AVB_AB_FLOW_RESULT_ERROR_OOM is
- * returned.
- *
- * If invalid arguments are passed,
- * AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT is returned. For example
- * this can happen if using AVB_HASHTREE_ERROR_MODE_LOGGING without
- * AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR.
- *
- * Reasonable behavior for handling AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS
- * is to initiate device repair (which is device-dependent).
- */
-AvbABFlowResult avb_ab_flow(AvbABOps* ab_ops,
- const char* const* requested_partitions,
- AvbSlotVerifyFlags flags,
- AvbHashtreeErrorMode hashtree_error_mode,
- AvbSlotVerifyData** out_data);
-
-/* Marks the slot with the given slot number as active. Returns
- * AVB_IO_RESULT_OK on success, error code otherwise.
- *
- * This function is typically used by the OS updater when completing
- * an update. It can also used by the firmware for implementing the
- * "set_active" command.
- */
-AvbIOResult avb_ab_mark_slot_active(AvbABOps* ab_ops, unsigned int slot_number);
-
-/* Marks the slot with the given slot number as unbootable. Returns
- * AVB_IO_RESULT_OK on success, error code otherwise.
- *
- * This function is typically used by the OS updater before writing to
- * a slot.
- */
-AvbIOResult avb_ab_mark_slot_unbootable(AvbABOps* ab_ops,
- unsigned int slot_number);
-
-/* Marks the slot with the given slot number as having booted
- * successfully. Returns AVB_IO_RESULT_OK on success, error code
- * otherwise.
- *
- * Calling this on an unbootable slot is an error - AVB_IO_RESULT_OK
- * will be returned yet the function will have no side-effects.
- *
- * This function is typically used by the OS updater after having
- * confirmed that the slot works as intended.
- */
-AvbIOResult avb_ab_mark_slot_successful(AvbABOps* ab_ops,
- unsigned int slot_number);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AVB_AB_FLOW_H_ */
diff --git a/lib/avb/libavb_ab/avb_ab_ops.h b/lib/avb/libavb_ab/avb_ab_ops.h
deleted file mode 100644
index 8d8fde7aa9..0000000000
--- a/lib/avb/libavb_ab/avb_ab_ops.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#if !defined(AVB_INSIDE_LIBAVB_AB_H) && !defined(AVB_COMPILATION)
-#error \
- "Never include this file directly, include libavb_ab/libavb_ab.h instead."
-#endif
-
-#ifndef AVB_AB_OPS_H_
-#define AVB_AB_OPS_H_
-
-#include <libavb/libavb.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct AvbABOps;
-typedef struct AvbABOps AvbABOps;
-
-struct AvbABData;
-
-/* High-level operations/functions/methods for A/B that are platform
- * dependent.
- */
-struct AvbABOps {
- /* Operations from libavb. */
- AvbOps* ops;
-
- /* Reads A/B metadata from persistent storage. Returned data is
- * properly byteswapped. Returns AVB_IO_RESULT_OK on success, error
- * code otherwise.
- *
- * If the data read is invalid (e.g. wrong magic or CRC checksum
- * failure), the metadata shoule be reset using avb_ab_data_init()
- * and then written to persistent storage.
- *
- * Implementations will typically want to use avb_ab_data_read()
- * here to use the 'misc' partition for persistent storage.
- */
- AvbIOResult (*read_ab_metadata)(AvbABOps* ab_ops, struct AvbABData* data);
-
- /* Writes A/B metadata to persistent storage. This will byteswap and
- * update the CRC as needed. Returns AVB_IO_RESULT_OK on success,
- * error code otherwise.
- *
- * Implementations will typically want to use avb_ab_data_write()
- * here to use the 'misc' partition for persistent storage.
- */
- AvbIOResult (*write_ab_metadata)(AvbABOps* ab_ops,
- const struct AvbABData* data);
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AVB_AB_OPS_H_ */
diff --git a/lib/avb/libavb_ab/libavb_ab.h b/lib/avb/libavb_ab/libavb_ab.h
deleted file mode 100644
index 654ff5e771..0000000000
--- a/lib/avb/libavb_ab/libavb_ab.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef LIBAVB_AB_H_
-#define LIBAVB_AB_H_
-
-#include <libavb/libavb.h>
-
-/* The libavb_ab/ and boot_control/ code has been marked for some time
- * as experimental in anticipation of being removed in the future. It
- * is now deprecated and to continue using it you must define
- * AVB_AB_I_UNDERSTAND_LIBAVB_AB_IS_DEPRECATED. It will be removed Jun
- * 1 2018.
- */
-#ifndef AVB_AB_I_UNDERSTAND_LIBAVB_AB_IS_DEPRECATED
-#error \
- "You must define AVB_AB_I_UNDERSTAND_LIBAVB_AB_IS_DEPRECATED to use this library."
-#endif
-
-/* The AVB_INSIDE_LIBAVB_AB_H preprocessor symbol is used to enforce
- * library users to include only this file. All public interfaces, and
- * only public interfaces, must be included here.
- */
-
-#define AVB_INSIDE_LIBAVB_AB_H
-#include "avb_ab_flow.h"
-#include "avb_ab_ops.h"
-#undef AVB_INSIDE_LIBAVB_AB_H
-
-#endif /* LIBAVB_AB_H_ */