1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 #include <android_ab.h> 8 9 #include <android_bootloader_message.h> 10 #include <common.h> 11 #include <malloc.h> 12 #include <u-boot/crc.h> 13 14 /** android_boot_control_compute_crc - Compute the CRC-32 of the bootloader 15 * control struct. Only the bytes up to the crc32_le field are considered for 16 * the CRC-32 calculation. 17 */ 18 static uint32_t android_boot_control_compute_crc( 19 struct android_bootloader_control *abc) 20 { 21 return crc32(0, (void *)abc, offsetof(typeof(*abc), crc32_le)); 22 } 23 24 /** android_boot_control_default - Initialize android_bootloader_control to the 25 * default value which allows to boot all slots in order from the first one. 26 * This value should be used when the bootloader message is corrupted, but not 27 * when a valid message indicates that all slots are unbootable. 28 */ 29 void android_boot_control_default(struct android_bootloader_control *abc) 30 { 31 int i; 32 const struct android_slot_metadata metadata = { 33 .priority = 15, 34 .tries_remaining = 7, 35 .successful_boot = 0, 36 .verity_corrupted = 0, 37 .reserved = 0 38 }; 39 memcpy(abc->slot_suffix, "a\0\0\0", 4); 40 abc->magic = ANDROID_BOOT_CTRL_MAGIC; 41 abc->version = ANDROID_BOOT_CTRL_VERSION; 42 abc->nb_slot = ARRAY_SIZE(abc->slot_info); 43 memset(abc->reserved0, 0, sizeof(abc->reserved0)); 44 for (i = 0; i < abc->nb_slot; ++i) { 45 abc->slot_info[i] = metadata; 46 } 47 memset(abc->reserved1, 0, sizeof(abc->reserved1)); 48 abc->crc32_le = android_boot_control_compute_crc(abc); 49 } 50 51 /** android_boot_control_create_from_disk 52 * Load the boot_control struct from disk into newly allocated memory. This 53 * function allocates and returns an integer number of disk blocks, based on the 54 * block size of the passed device to help performing a read-modify-write 55 * operation on the boot_control struct. The boot_control struct offset (2 KiB) 56 * must be a multiple of the device block size, for simplicity. 57 * @dev_desc: device where to read the boot_control struct from. 58 * @part_info: partition in 'dev_desc' where to read from, normally the "misc" 59 * partition should be used. 60 */ 61 static void *android_boot_control_create_from_disk( 62 struct blk_desc *dev_desc, 63 const disk_partition_t *part_info) 64 { 65 ulong abc_offset, abc_blocks; 66 void *buf; 67 68 abc_offset = offsetof(struct android_bootloader_message_ab, 69 slot_suffix); 70 if (abc_offset % part_info->blksz) { 71 printf("ANDROID: Boot control block not block aligned.\n"); 72 return NULL; 73 } 74 abc_offset /= part_info->blksz; 75 76 abc_blocks = DIV_ROUND_UP(sizeof(struct android_bootloader_control), 77 part_info->blksz); 78 if (abc_offset + abc_blocks > part_info->size) { 79 printf("ANDROID: boot control partition too small. Need at" 80 " least %lu blocks but have %lu blocks.\n", 81 abc_offset + abc_blocks, part_info->size); 82 return NULL; 83 } 84 buf = malloc(abc_blocks * part_info->blksz); 85 if (!buf) 86 return NULL; 87 88 if (blk_dread(dev_desc, part_info->start + abc_offset, abc_blocks, 89 buf) != abc_blocks) { 90 printf("ANDROID: Could not read from boot control partition\n"); 91 free(buf); 92 return NULL; 93 } 94 debug("ANDROID: Loaded ABC, %lu blocks.\n", abc_blocks); 95 return buf; 96 } 97 98 /** android_boot_control_store 99 * Store the loaded boot_control block back to the same location it was read 100 * from with android_boot_control_create_from_misc(). 101 * 102 * @abc_data_block: pointer to the boot_control struct and the extra bytes after 103 * it up to the nearest block boundary. 104 * @dev_desc: device where we should write the boot_control struct. 105 * @part_info: partition on the 'dev_desc' where to write. 106 * @return 0 on success and -1 on error. 107 */ 108 static int android_boot_control_store(void *abc_data_block, 109 struct blk_desc *dev_desc, 110 const disk_partition_t *part_info) 111 { 112 ulong abc_offset, abc_blocks; 113 114 abc_offset = offsetof(struct android_bootloader_message_ab, 115 slot_suffix) / part_info->blksz; 116 abc_blocks = DIV_ROUND_UP(sizeof(struct android_bootloader_control), 117 part_info->blksz); 118 if (blk_dwrite(dev_desc, part_info->start + abc_offset, abc_blocks, 119 abc_data_block) != abc_blocks) { 120 printf("ANDROID: Could not write back the misc partition\n"); 121 return -1; 122 } 123 return 0; 124 } 125 126 /** android_boot_compare_slots - compares two slots returning which slot is 127 * should we boot from among the two. 128 * @a: The first bootable slot metadata 129 * @b: The second bootable slot metadata 130 * @return negative if the slot "a" is better, positive of the slot "b" is 131 * better or 0 if they are equally good. 132 */ 133 static int android_ab_compare_slots(const struct android_slot_metadata *a, 134 const struct android_slot_metadata *b) 135 { 136 /* Higher priority is better */ 137 if (a->priority != b->priority) 138 return b->priority - a->priority; 139 140 /* Higher successful_boot value is better, in case of same priority. */ 141 if (a->successful_boot != b->successful_boot) 142 return b->successful_boot - a->successful_boot; 143 144 /* Higher tries_remaining is better to ensure round-robin. */ 145 if (a->tries_remaining != b->tries_remaining) 146 return b->tries_remaining - a->tries_remaining; 147 148 return 0; 149 } 150 151 int android_ab_select(struct blk_desc *dev_desc, disk_partition_t *part_info) 152 { 153 struct android_bootloader_control *abc; 154 u32 crc32_le; 155 int slot, i; 156 bool store_needed = false; 157 char slot_suffix[4]; 158 159 abc = android_boot_control_create_from_disk(dev_desc, part_info); 160 if (!abc) { 161 /* This condition represents an actual problem with the code 162 * or the board setup, like an invalid partition information. 163 * Signal a repair mode and do not try to boot from either 164 * slot. 165 */ 166 return -1; 167 } 168 169 crc32_le = android_boot_control_compute_crc(abc); 170 if (abc->crc32_le != crc32_le) { 171 printf("ANDROID: Invalid CRC-32 (expected %.8x, found %.8x), " 172 "re-initializing A/B metadata.\n", 173 crc32_le, abc->crc32_le); 174 android_boot_control_default(abc); 175 store_needed = true; 176 } 177 178 if (abc->magic != ANDROID_BOOT_CTRL_MAGIC) { 179 printf("ANDROID: Unknown A/B metadata: %.8x\n", abc->magic); 180 free(abc); 181 return -1; 182 } 183 184 if (abc->version > ANDROID_BOOT_CTRL_VERSION) { 185 printf("ANDROID: Unsupported A/B metadata version: %.8x\n", 186 abc->version); 187 free(abc); 188 return -1; 189 } 190 191 /* At this point a valid boot control metadata is stored in abc, 192 * followed by other reserved data in the same block. 193 * We select a with the higher priority slot that 194 * - is not marked as corrupted and 195 * - either has tries_remaining > 0 or successful_boot is true. 196 * If the slot selected has a false successful_boot, we also decrement 197 * the tries_remaining until it eventually becomes unbootable because 198 * tries_remaining reaches 0. This mechanism produces a bootloader 199 * induced rollback, typically right after a failed update. 200 */ 201 202 /* Safety check: limit the number of slots. */ 203 if (abc->nb_slot > ARRAY_SIZE(abc->slot_info)) { 204 abc->nb_slot = ARRAY_SIZE(abc->slot_info); 205 store_needed = true; 206 } 207 208 slot = -1; 209 for (i = 0; i < abc->nb_slot; ++i) { 210 if (abc->slot_info[i].verity_corrupted || 211 !abc->slot_info[i].tries_remaining) { 212 debug("ANDROID: unbootable slot %d tries: %d, " 213 "corrupt: %d\n", 214 i, 215 abc->slot_info[i].tries_remaining, 216 abc->slot_info[i].verity_corrupted); 217 continue; 218 } 219 debug("ANDROID: bootable slot %d pri: %d, tries: %d, " 220 "corrupt: %d, successful: %d\n", 221 i, 222 abc->slot_info[i].priority, 223 abc->slot_info[i].tries_remaining, 224 abc->slot_info[i].verity_corrupted, 225 abc->slot_info[i].successful_boot); 226 227 if (slot < 0 || 228 android_ab_compare_slots(&abc->slot_info[i], 229 &abc->slot_info[slot]) < 0) { 230 slot = i; 231 } 232 } 233 234 if (slot >= 0 && !abc->slot_info[slot].successful_boot) { 235 printf("ANDROID: Attempting slot %c, tries remaining %d\n", 236 ANDROID_BOOT_SLOT_NAME(slot), 237 abc->slot_info[slot].tries_remaining); 238 abc->slot_info[slot].tries_remaining--; 239 store_needed = true; 240 } 241 242 if (slot >= 0) { 243 /* Legacy user-space requires this field to be set in the BCB. 244 * Newer releases load this the slot suffix from the command 245 * line or the device tree. 246 */ 247 memset(slot_suffix, 0, sizeof(slot_suffix)); 248 slot_suffix[0] = ANDROID_BOOT_SLOT_NAME(slot); 249 if (memcmp(abc->slot_suffix, slot_suffix, 250 sizeof(slot_suffix))) { 251 memcpy(abc->slot_suffix, slot_suffix, 252 sizeof(slot_suffix)); 253 store_needed = true; 254 } 255 } 256 257 if (store_needed) { 258 abc->crc32_le = android_boot_control_compute_crc(abc); 259 android_boot_control_store(abc, dev_desc, part_info); 260 } 261 free(abc); 262 263 if (slot < 0) 264 return -1; 265 return slot; 266 } 267