Set the initial 'source_slot' in 'misc_virtual_ab_message' as
the current slot. At the same time, add slot checks before
erase data if virtual A/B is enabled.
Test: virtual A/B update and erase.
Signed-off-by: Ji Luo <ji.luo@nxp.com>
Change-Id: I84896335a95d9188b85e114037b470b3f4e7a209
(cherry picked from commit
a522c2245c3e58adbbcb99c43e0917ce315cc1aa)
(cherry picked from commit
40a1e64ded230e1c2b3d76cccaea1f910ed0d6d6)
#endif
#ifdef CONFIG_VIRTUAL_AB_SUPPORT
- if (virtual_ab_update_is_merging() || virtual_ab_update_is_snapshoted()) {
+ if (virtual_ab_update_is_merging() ||
+ (virtual_ab_update_is_snapshoted() && !virtual_ab_slot_match())) {
printf("Can not erase userdata while a snapshot update is in progress!\n");
return FASTBOOT_LOCK_ERROR;
}
}
#ifdef CONFIG_VIRTUAL_AB_SUPPORT
- if (virtual_ab_update_is_merging() || virtual_ab_update_is_snapshoted()) {
+ if (virtual_ab_update_is_merging() ||
+ (virtual_ab_update_is_snapshoted() && !virtual_ab_slot_match())) {
printf("Can not erase userdata while a snapshot update is in progress!\n");
return FASTBOOT_LOCK_ERROR;
}
static int read_virtual_ab_message(misc_virtual_ab_message *message)
{
size_t num_bytes;
+ int source_slot;
if (fsl_read_from_partition_multi(NULL, FASTBOOT_PARTITION_MISC,
SYSTEM_SPACE_SIZE_IN_MISC,
if ((message->magic != MISC_VIRTUAL_AB_MAGIC_HEADER) ||
(message->version != MISC_VIRTUAL_AB_MESSAGE_VERSION)) {
- printf("Invalid virtual AB status, resetting...");
+ printf("Invalid virtual AB status, resetting...\n");
message->version = MISC_VIRTUAL_AB_MESSAGE_VERSION;
message->magic = MISC_VIRTUAL_AB_MAGIC_HEADER;
message->merge_status = VIRTUAL_AB_NONE;
- message->source_slot = 0;
+
+ /* Reset the source slot as the current slot */
+ source_slot = current_slot();
+ if (source_slot != -1)
+ message->source_slot = source_slot;
+ else
+ return -1;
+
if (fsl_write_to_partition(NULL, FASTBOOT_PARTITION_MISC,
SYSTEM_SPACE_SIZE_IN_MISC,
sizeof(misc_virtual_ab_message),
if ((!strncmp(part, "misc", sizeof("misc")) ||
!strncmp(part, "userdata", sizeof("userdata")) ||
!strncmp(part, "metadata", sizeof("metadata"))) &&
- (virtual_ab_update_is_merging() || virtual_ab_update_is_snapshoted()))
+ (virtual_ab_update_is_merging() ||
+ (virtual_ab_update_is_snapshoted() && !virtual_ab_slot_match())))
return true;
else
return false;
return false;
}
+bool virtual_ab_slot_match(void)
+{
+ misc_virtual_ab_message message;
+ read_virtual_ab_message(&message);
+
+ if (message.source_slot == current_slot())
+ return true;
+ else
+ return false;
+}
+
int virtual_ab_cancel_update(void)
{
misc_virtual_ab_message message;
bool partition_is_protected_during_merge(char *part);
bool virtual_ab_update_is_merging(void);
bool virtual_ab_update_is_snapshoted(void);
+bool virtual_ab_slot_match(void);
int virtual_ab_cancel_update(void);
* hardware/interfaces/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
*/
#define FSL_AB_METADATA_MISC_PARTITION_OFFSET 2048
+extern AvbABOps fsl_avb_ab_ops;
static char *slot_suffix[AVB_AB_SLOT_NUM] = {"_a", "_b"};
return -1;
}
+/* Return current slot without passing 'bootloader_control' struct */
+int current_slot(void) {
+ struct bootloader_control ab_data;
+
+ /* Load A/B metadata and decide which slot we are going to load */
+ if (fsl_avb_ab_ops.read_ab_metadata(&fsl_avb_ab_ops, &ab_data) !=
+ AVB_IO_RESULT_OK) {
+ printf("Error loading AB metadata from misc!\n");
+ return -1;
+ }
+ return get_curr_slot(&ab_data);
+}
+
int slotidx_from_suffix(char *suffix) {
int slot = -1;
return ret;
}
-extern AvbABOps fsl_avb_ab_ops;
static bool spl_recovery_flag = false;
bool is_spl_recovery(void)
{
* */
int get_curr_slot(struct bootloader_control* ab_data);
+/* Get current bootable slot without passing the "bootloader_control" struct.
+ * return 0 for the first slot
+ * return 1 for the second slot
+ * return -1 for not supported slot
+ * */
+int current_slot(void);
+
/* return 0 for the first slot
* return 1 for the second slot
* return -1 for not supported slot