diff options
author | Ji Luo <ji.luo@nxp.com> | 2019-02-21 15:45:05 +0800 |
---|---|---|
committer | Ji Luo <ji.luo@nxp.com> | 2019-02-21 19:38:14 +0800 |
commit | 7adbca6deaa6b41026655a6d5a12ebfccb3168a2 (patch) | |
tree | 5fe817f3402f87c2cf304024ef3048b4ad753f30 /lib | |
parent | a418bbd42ce5a8c2773640fe64ad2c5bb2ea4cfa (diff) |
MA-14118 Avoid slot switch if retry count exhaust in spl
The A/B slot is chosen at spl stage and should be kept up to
u-boot stage. Decrease slot retry count will cause slot switch
when the slot only has one chance left.
Set the 'bootloader_verified' flag when current slot is running the last
chance at spl, u-boot will treat the slot as bootable if the
'reserved' flag is set even the retry count exhausted.
Test: Slot not switch during 7 times reboot try.
Change-Id: I7ae84b2ce683300a1bb332606cd58e48483214ea
Signed-off-by: Ji Luo <ji.luo@nxp.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/avb/fsl/fsl_avb_ab_flow.c | 18 | ||||
-rwxr-xr-x | lib/avb/fsl/fsl_bootctl.c | 9 | ||||
-rw-r--r-- | lib/avb/libavb_ab/avb_ab_flow.c | 9 | ||||
-rw-r--r-- | lib/avb/libavb_ab/avb_ab_flow.h | 2 |
4 files changed, 37 insertions, 1 deletions
diff --git a/lib/avb/fsl/fsl_avb_ab_flow.c b/lib/avb/fsl/fsl_avb_ab_flow.c index f015bad105..efe202b644 100644 --- a/lib/avb/fsl/fsl_avb_ab_flow.c +++ b/lib/avb/fsl/fsl_avb_ab_flow.c @@ -31,10 +31,18 @@ void fsl_slot_set_unbootable(AvbABSlotData* slot) { */ void fsl_slot_normalize(AvbABSlotData* 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)) { + /* We've exhausted all tries -> unbootable. */ + fsl_slot_set_unbootable(slot); + } +#else if ((slot->tries_remaining == 0) && (!slot->successful_boot)) { /* 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. @@ -88,9 +96,11 @@ void fsl_avb_ab_data_init(AvbABData* data) { 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; } bool fsl_avb_ab_data_verify_and_byteswap(const AvbABData* src, @@ -361,6 +371,9 @@ int mmc_load_image_parse_container_dual_uboot( goto end; } else if (!ab_data.slots[slot_index_to_boot].successful_boot && (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) { + /* Set the bootloader_verified flag 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; } printf("Booting from bootloader%s...\n", slot_suffixes[slot_index_to_boot]); @@ -500,6 +513,9 @@ int mmc_load_image_raw_sector_dual_uboot( goto end; } else if (!ab_data.slots[slot_index_to_boot].successful_boot && (ab_data.slots[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; } printf("Booting from bootloader%s...\n", slot_suffixes[slot_index_to_boot]); @@ -623,6 +639,8 @@ AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops, printf("No bootable slot found!\n"); goto out; } + /* Clear the bootloader_verified flag. */ + ab_data.slots[target_slot].bootloader_verified = 0; printf("Verifying slot %s ...\n", slot_suffixes[target_slot]); verify_result = avb_slot_verify(ops, diff --git a/lib/avb/fsl/fsl_bootctl.c b/lib/avb/fsl/fsl_bootctl.c index b7b02e2b84..8f853bc807 100755 --- a/lib/avb/fsl/fsl_bootctl.c +++ b/lib/avb/fsl/fsl_bootctl.c @@ -25,8 +25,17 @@ static int strcmp_l1(const char *s1, const char *s2) { } 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) { diff --git a/lib/avb/libavb_ab/avb_ab_flow.c b/lib/avb/libavb_ab/avb_ab_flow.c index bf6eab1542..6097988b19 100644 --- a/lib/avb/libavb_ab/avb_ab_flow.c +++ b/lib/avb/libavb_ab/avb_ab_flow.c @@ -67,9 +67,15 @@ void avb_ab_data_init(AvbABData* data) { 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 @@ -423,6 +429,9 @@ AvbIOResult avb_ab_mark_slot_active(AvbABOps* ab_ops, 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; diff --git a/lib/avb/libavb_ab/avb_ab_flow.h b/lib/avb/libavb_ab/avb_ab_flow.h index 588026d5a5..3757ba26ac 100644 --- a/lib/avb/libavb_ab/avb_ab_flow.h +++ b/lib/avb/libavb_ab/avb_ab_flow.h @@ -72,7 +72,7 @@ typedef struct AvbABSlotData { uint8_t successful_boot; /* Reserved for future use. */ - uint8_t reserved[1]; + uint8_t bootloader_verified; } AVB_ATTR_PACKED AvbABSlotData; /* Struct used for recording A/B metadata. |