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 <android_image.h> 11 #include <boot_rkimg.h> 12 #include <common.h> 13 #include <malloc.h> 14 #include <android_avb/avb_ops_user.h> 15 #include <android_avb/rk_avb_ops_user.h> 16 #include <u-boot/crc.h> 17 #include <boot_rkimg.h> 18 19 /** android_boot_control_compute_crc - Compute the CRC-32 of the bootloader 20 * control struct. Only the bytes up to the crc32_le field are considered for 21 * the CRC-32 calculation. 22 */ 23 static uint32_t android_boot_control_compute_crc( 24 struct android_bootloader_control *abc) 25 { 26 return crc32(0, (void *)abc, offsetof(typeof(*abc), crc32_le)); 27 } 28 29 /** android_boot_control_default - Initialize android_bootloader_control to the 30 * default value which allows to boot all slots in order from the first one. 31 * This value should be used when the bootloader message is corrupted, but not 32 * when a valid message indicates that all slots are unbootable. 33 */ 34 void android_boot_control_default(struct android_bootloader_control *abc) 35 { 36 int i; 37 const struct android_slot_metadata metadata = { 38 .priority = 15, 39 .tries_remaining = 7, 40 .successful_boot = 0, 41 .verity_corrupted = 0, 42 .reserved = 0 43 }; 44 memcpy(abc->slot_suffix, "a\0\0\0", 4); 45 abc->magic = ANDROID_BOOT_CTRL_MAGIC; 46 abc->version = ANDROID_BOOT_CTRL_VERSION; 47 abc->nb_slot = ARRAY_SIZE(abc->slot_info); 48 memset(abc->reserved0, 0, sizeof(abc->reserved0)); 49 for (i = 0; i < abc->nb_slot; ++i) { 50 abc->slot_info[i] = metadata; 51 } 52 memset(abc->reserved1, 0, sizeof(abc->reserved1)); 53 abc->crc32_le = android_boot_control_compute_crc(abc); 54 } 55 56 /** android_boot_control_create_from_disk 57 * Load the boot_control struct from disk into newly allocated memory. This 58 * function allocates and returns an integer number of disk blocks, based on the 59 * block size of the passed device to help performing a read-modify-write 60 * operation on the boot_control struct. The boot_control struct offset (2 KiB) 61 * must be a multiple of the device block size, for simplicity. 62 * @dev_desc: device where to read the boot_control struct from. 63 * @part_info: partition in 'dev_desc' where to read from, normally the "misc" 64 * partition should be used. 65 */ 66 static void *android_boot_control_create_from_disk( 67 struct blk_desc *dev_desc, 68 const disk_partition_t *part_info) 69 { 70 ulong abc_offset, abc_blocks; 71 void *buf; 72 73 abc_offset = offsetof(struct android_bootloader_message_ab, 74 slot_suffix); 75 if (abc_offset % part_info->blksz) { 76 printf("ANDROID: Boot control block not block aligned.\n"); 77 return NULL; 78 } 79 abc_offset /= part_info->blksz; 80 81 abc_blocks = DIV_ROUND_UP(sizeof(struct android_bootloader_control), 82 part_info->blksz); 83 if (abc_offset + abc_blocks > part_info->size) { 84 printf("ANDROID: boot control partition too small. Need at" 85 " least %lu blocks but have %lu blocks.\n", 86 abc_offset + abc_blocks, part_info->size); 87 return NULL; 88 } 89 buf = malloc(abc_blocks * part_info->blksz); 90 if (!buf) 91 return NULL; 92 93 if (blk_dread(dev_desc, part_info->start + abc_offset, abc_blocks, 94 buf) != abc_blocks) { 95 printf("ANDROID: Could not read from boot control partition\n"); 96 free(buf); 97 return NULL; 98 } 99 debug("ANDROID: Loaded ABC, %lu blocks.\n", abc_blocks); 100 return buf; 101 } 102 103 /** android_boot_control_store 104 * Store the loaded boot_control block back to the same location it was read 105 * from with android_boot_control_create_from_misc(). 106 * 107 * @abc_data_block: pointer to the boot_control struct and the extra bytes after 108 * it up to the nearest block boundary. 109 * @dev_desc: device where we should write the boot_control struct. 110 * @part_info: partition on the 'dev_desc' where to write. 111 * @return 0 on success and -1 on error. 112 */ 113 static int android_boot_control_store(void *abc_data_block, 114 struct blk_desc *dev_desc, 115 const disk_partition_t *part_info) 116 { 117 ulong abc_offset, abc_blocks; 118 119 abc_offset = offsetof(struct android_bootloader_message_ab, 120 slot_suffix) / part_info->blksz; 121 abc_blocks = DIV_ROUND_UP(sizeof(struct android_bootloader_control), 122 part_info->blksz); 123 if (blk_dwrite(dev_desc, part_info->start + abc_offset, abc_blocks, 124 abc_data_block) != abc_blocks) { 125 printf("ANDROID: Could not write back the misc partition\n"); 126 return -1; 127 } 128 return 0; 129 } 130 131 /** android_boot_compare_slots - compares two slots returning which slot is 132 * should we boot from among the two. 133 * @a: The first bootable slot metadata 134 * @b: The second bootable slot metadata 135 * @return negative if the slot "a" is better, positive of the slot "b" is 136 * better or 0 if they are equally good. 137 */ 138 static int android_ab_compare_slots(const struct android_slot_metadata *a, 139 const struct android_slot_metadata *b) 140 { 141 /* Higher priority is better */ 142 if (a->priority != b->priority) 143 return b->priority - a->priority; 144 145 /* Higher successful_boot value is better, in case of same priority. */ 146 if (a->successful_boot != b->successful_boot) 147 return b->successful_boot - a->successful_boot; 148 149 /* Higher tries_remaining is better to ensure round-robin. */ 150 if (a->tries_remaining != b->tries_remaining) 151 return b->tries_remaining - a->tries_remaining; 152 153 return 0; 154 } 155 156 int android_ab_select(struct blk_desc *dev_desc, disk_partition_t *part_info) 157 { 158 struct android_bootloader_control *abc; 159 u32 crc32_le; 160 int slot, i; 161 bool store_needed = false; 162 char slot_suffix[4]; 163 164 abc = android_boot_control_create_from_disk(dev_desc, part_info); 165 if (!abc) { 166 /* This condition represents an actual problem with the code 167 * or the board setup, like an invalid partition information. 168 * Signal a repair mode and do not try to boot from either 169 * slot. 170 */ 171 return -1; 172 } 173 174 crc32_le = android_boot_control_compute_crc(abc); 175 if (abc->crc32_le != crc32_le) { 176 printf("ANDROID: Invalid CRC-32 (expected %.8x, found %.8x), " 177 "re-initializing A/B metadata.\n", 178 crc32_le, abc->crc32_le); 179 android_boot_control_default(abc); 180 store_needed = true; 181 } 182 183 if (abc->magic != ANDROID_BOOT_CTRL_MAGIC) { 184 printf("ANDROID: Unknown A/B metadata: %.8x\n", abc->magic); 185 free(abc); 186 return -1; 187 } 188 189 if (abc->version > ANDROID_BOOT_CTRL_VERSION) { 190 printf("ANDROID: Unsupported A/B metadata version: %.8x\n", 191 abc->version); 192 free(abc); 193 return -1; 194 } 195 196 /* At this point a valid boot control metadata is stored in abc, 197 * followed by other reserved data in the same block. 198 * We select a with the higher priority slot that 199 * - is not marked as corrupted and 200 * - either has tries_remaining > 0 or successful_boot is true. 201 * If the slot selected has a false successful_boot, we also decrement 202 * the tries_remaining until it eventually becomes unbootable because 203 * tries_remaining reaches 0. This mechanism produces a bootloader 204 * induced rollback, typically right after a failed update. 205 */ 206 207 /* Safety check: limit the number of slots. */ 208 if (abc->nb_slot > ARRAY_SIZE(abc->slot_info)) { 209 abc->nb_slot = ARRAY_SIZE(abc->slot_info); 210 store_needed = true; 211 } 212 213 slot = -1; 214 for (i = 0; i < abc->nb_slot; ++i) { 215 if (abc->slot_info[i].verity_corrupted || 216 !abc->slot_info[i].tries_remaining) { 217 debug("ANDROID: unbootable slot %d tries: %d, " 218 "corrupt: %d\n", 219 i, 220 abc->slot_info[i].tries_remaining, 221 abc->slot_info[i].verity_corrupted); 222 continue; 223 } 224 debug("ANDROID: bootable slot %d pri: %d, tries: %d, " 225 "corrupt: %d, successful: %d\n", 226 i, 227 abc->slot_info[i].priority, 228 abc->slot_info[i].tries_remaining, 229 abc->slot_info[i].verity_corrupted, 230 abc->slot_info[i].successful_boot); 231 232 if (slot < 0 || 233 android_ab_compare_slots(&abc->slot_info[i], 234 &abc->slot_info[slot]) < 0) { 235 slot = i; 236 } 237 } 238 239 if (slot >= 0 && !abc->slot_info[slot].successful_boot) { 240 printf("ANDROID: Attempting slot %c, tries remaining %d\n", 241 ANDROID_BOOT_SLOT_NAME(slot), 242 abc->slot_info[slot].tries_remaining); 243 abc->slot_info[slot].tries_remaining--; 244 store_needed = true; 245 } 246 247 if (slot >= 0) { 248 /* Legacy user-space requires this field to be set in the BCB. 249 * Newer releases load this the slot suffix from the command 250 * line or the device tree. 251 */ 252 memset(slot_suffix, 0, sizeof(slot_suffix)); 253 slot_suffix[0] = ANDROID_BOOT_SLOT_NAME(slot); 254 if (memcmp(abc->slot_suffix, slot_suffix, 255 sizeof(slot_suffix))) { 256 memcpy(abc->slot_suffix, slot_suffix, 257 sizeof(slot_suffix)); 258 store_needed = true; 259 } 260 } 261 262 if (store_needed) { 263 abc->crc32_le = android_boot_control_compute_crc(abc); 264 android_boot_control_store(abc, dev_desc, part_info); 265 } 266 free(abc); 267 268 if (slot < 0) 269 return -1; 270 return slot; 271 } 272 273 int read_misc_virtual_ab_message(struct misc_virtual_ab_message *message) 274 { 275 struct blk_desc *dev_desc; 276 disk_partition_t part_info; 277 u32 bcb_offset = (ANDROID_VIRTUAL_AB_METADATA_OFFSET_IN_MISC >> 9); 278 int cnt, ret; 279 280 if (!message) { 281 debug("%s: message is NULL!\n", __func__); 282 return -1; 283 } 284 285 dev_desc = rockchip_get_bootdev(); 286 if (!dev_desc) { 287 debug("%s: dev_desc is NULL!\n", __func__); 288 return -1; 289 } 290 291 ret = part_get_info_by_name(dev_desc, PART_MISC, &part_info); 292 if (ret < 0) { 293 debug("%s: Could not found misc partition\n", 294 __func__); 295 return -1; 296 } 297 298 cnt = DIV_ROUND_UP(sizeof(struct misc_virtual_ab_message), dev_desc->blksz); 299 if (blk_dread(dev_desc, part_info.start + bcb_offset, cnt, message) != cnt) { 300 debug("%s: could not read from misc partition\n", __func__); 301 return -1; 302 } 303 304 return 0; 305 } 306 307 int write_misc_virtual_ab_message(struct misc_virtual_ab_message *message) 308 { 309 struct blk_desc *dev_desc; 310 disk_partition_t part_info; 311 u32 bcb_offset = (ANDROID_VIRTUAL_AB_METADATA_OFFSET_IN_MISC >> 9); 312 int cnt, ret; 313 314 if (!message) { 315 debug("%s: message is NULL!\n", __func__); 316 return -1; 317 } 318 319 dev_desc = rockchip_get_bootdev(); 320 if (!dev_desc) { 321 debug("%s: dev_desc is NULL!\n", __func__); 322 return -1; 323 } 324 325 ret = part_get_info_by_name(dev_desc, PART_MISC, &part_info); 326 if (ret < 0) { 327 debug("%s: Could not found misc partition\n", 328 __func__); 329 return -1; 330 } 331 332 cnt = DIV_ROUND_UP(sizeof(struct misc_virtual_ab_message), dev_desc->blksz); 333 ret = blk_dwrite(dev_desc, part_info.start + bcb_offset, cnt, message); 334 if (ret != cnt) 335 debug("%s: blk_dwrite write failed, ret=%d\n", __func__, ret); 336 337 return 0; 338 } 339 340 int ab_is_support_dynamic_partition(struct blk_desc *dev_desc) 341 { 342 disk_partition_t super_part_info; 343 disk_partition_t boot_part_info; 344 int part_num; 345 int is_dp = 0; 346 char *super_dp = NULL; 347 char *super_info = "androidboot.super_partition="; 348 349 memset(&super_part_info, 0x0, sizeof(super_part_info)); 350 part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_SUPER, 351 &super_part_info); 352 if (part_num < 0) { 353 memset(&boot_part_info, 0x0, sizeof(boot_part_info)); 354 part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_BOOT, 355 &boot_part_info); 356 if (part_num < 0) { 357 is_dp = 0; 358 } else { 359 andr_img_hdr hdr; 360 ulong hdr_blocks = sizeof(struct andr_img_hdr) / 361 boot_part_info.blksz; 362 363 memset(&hdr, 0x0, sizeof(hdr)); 364 if (blk_dread(dev_desc, boot_part_info.start, hdr_blocks, &hdr) != 365 hdr_blocks) { 366 is_dp = 0; 367 } else { 368 debug("hdr cmdline=%s\n", hdr.cmdline); 369 super_dp = strstr(hdr.cmdline, super_info); 370 if (super_dp) 371 is_dp = 1; 372 else 373 is_dp = 0; 374 } 375 } 376 } else { 377 debug("Find super partition, the firmware support dynamic partition\n"); 378 is_dp = 1; 379 } 380 381 debug("%s is_dp=%d\n", __func__, is_dp); 382 return is_dp; 383 } 384 385 static int get_partition_unique_uuid(char *partition, 386 char *guid_buf, 387 size_t guid_buf_size) 388 { 389 #if CONFIG_IS_ENABLED(PARTITION_UUIDS) 390 struct blk_desc *dev_desc; 391 disk_partition_t part_info; 392 393 dev_desc = rockchip_get_bootdev(); 394 if (!dev_desc) { 395 printf("%s: Could not find device\n", __func__); 396 return -1; 397 } 398 399 if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 400 printf("Could not find \"%s\" partition\n", partition); 401 return -1; 402 } 403 404 if (guid_buf && guid_buf_size > 0) 405 memcpy(guid_buf, part_info.uuid, guid_buf_size); 406 407 return 0; 408 #else 409 printf("WARN: Get partition uuid requires CONFIG_PARTITION_UUIDS enabled\n"); 410 return -1; 411 #endif 412 } 413 414 static void ab_update_root_uuid(void) 415 { 416 /* 417 * In android a/b & avb process, the system.img is mandory and the 418 * "root=" will be added in vbmeta.img. 419 * 420 * In linux a/b & avb process, the system is NOT mandory and the 421 * "root=" will not be added in vbmeta.img but in kernel dts bootargs. 422 * (Parsed and dropped late, i.e. "root=" is not available now/always). 423 * 424 * To compatible with the above two processes, test the existence of 425 * "root=" and create it for linux ab & avb. 426 */ 427 char root_partuuid[70] = "root=PARTUUID="; 428 char *boot_args = env_get("bootargs"); 429 char guid_buf[UUID_SIZE] = {0}; 430 struct blk_desc *dev_desc; 431 432 dev_desc = rockchip_get_bootdev(); 433 if (!dev_desc) { 434 printf("%s: Could not find device\n", __func__); 435 return; 436 } 437 438 if (ab_is_support_dynamic_partition(dev_desc)) 439 return; 440 441 if (!strstr(boot_args, "root=")) { 442 get_partition_unique_uuid(ANDROID_PARTITION_SYSTEM, 443 guid_buf, UUID_SIZE); 444 strcat(root_partuuid, guid_buf); 445 env_update("bootargs", root_partuuid); 446 } 447 } 448 449 void ab_update_root_partition(void) 450 { 451 char *boot_args = env_get("bootargs"); 452 char root_part_dev[64] = {0}; 453 disk_partition_t part_info; 454 struct blk_desc *dev_desc; 455 const char *part_type; 456 int part_num; 457 458 dev_desc = rockchip_get_bootdev(); 459 if (!dev_desc) 460 return; 461 462 if (ab_is_support_dynamic_partition(dev_desc)) 463 return; 464 465 /* Get 'system' partition device number. */ 466 part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_SYSTEM, &part_info); 467 if (part_num < 0) { 468 printf("%s: Failed to get partition '%s'.\n", __func__, ANDROID_PARTITION_SYSTEM); 469 return; 470 } 471 472 /* Get partition type. */ 473 part_type = part_get_type(dev_desc); 474 if (!part_type) 475 return; 476 477 /* Judge the partition device type. */ 478 switch (dev_desc->if_type) { 479 case IF_TYPE_MMC: 480 case IF_TYPE_SCSI: /* scsi 0: UFS */ 481 if (strstr(part_type, "ENV")) 482 snprintf(root_part_dev, 64, "root=/dev/mmcblk0p%d", part_num); 483 else if (strstr(part_type, "EFI")) 484 ab_update_root_uuid(); 485 break; 486 case IF_TYPE_SPINAND: 487 if (strstr(part_type, "ENV")) 488 /* TODO */ 489 printf("%s: TODO: ENV partition for 'IF_TYPE_SPINAND'.\n", __func__); 490 else if (strstr(part_type, "EFI")) 491 ab_update_root_uuid(); 492 break; 493 case IF_TYPE_MTD: 494 if (dev_desc->devnum == BLK_MTD_NAND || dev_desc->devnum == BLK_MTD_SPI_NAND) { 495 if (strstr(boot_args, "rootfstype=squashfs") || strstr(boot_args, "rootfstype=erofs")) 496 snprintf(root_part_dev, 64, "ubi.mtd=%d root=/dev/ubiblock0_0", part_num - 1); 497 else if (strstr(boot_args, "rootfstype=ubifs")) 498 snprintf(root_part_dev, 64, "ubi.mtd=%d root=ubi0:system", part_num - 1); 499 } else if (dev_desc->devnum == BLK_MTD_SPI_NOR) { 500 snprintf(root_part_dev, 64, "root=/dev/mtdblock%d", part_num - 1); 501 } 502 break; 503 default: 504 ab_update_root_uuid(); 505 printf("Unknown part type, set default 'root=' with UUID.\n"); 506 return; 507 } 508 509 env_update("bootargs", root_part_dev); 510 } 511 512 int ab_get_slot_suffix(char *slot_suffix) 513 { 514 /* TODO: get from pre-loader or misc partition */ 515 if (rk_avb_get_current_slot(slot_suffix)) { 516 printf("rk_avb_get_current_slot() failed\n"); 517 return -1; 518 } 519 520 if (slot_suffix[0] != '_') { 521 #ifndef CONFIG_ANDROID_AVB 522 printf("###There is no bootable slot, bring up lastboot!###\n"); 523 if (rk_get_lastboot() == 1) 524 memcpy(slot_suffix, "_b", 2); 525 else if (rk_get_lastboot() == 0) 526 memcpy(slot_suffix, "_a", 2); 527 else 528 #endif 529 return -1; 530 } 531 532 return 0; 533 } 534 535 int ab_decrease_tries(void) 536 { 537 AvbABData ab_data_orig; 538 AvbABData ab_data; 539 char slot_suffix[3] = {0}; 540 AvbOps *ops; 541 size_t slot_index = 0; 542 543 if (ab_get_slot_suffix(slot_suffix)) 544 return -1; 545 546 if (!strncmp(slot_suffix, "_a", 2)) 547 slot_index = 0; 548 else if (!strncmp(slot_suffix, "_b", 2)) 549 slot_index = 1; 550 else 551 slot_index = 0; 552 553 ops = avb_ops_user_new(); 554 if (!ops) { 555 printf("avb_ops_user_new() failed!\n"); 556 return -1; 557 } 558 559 if (load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) { 560 printf("Can not load metadata\n"); 561 return -1; 562 } 563 564 /* ... and decrement tries remaining, if applicable. */ 565 if (!ab_data.slots[slot_index].successful_boot && 566 ab_data.slots[slot_index].tries_remaining > 0) 567 ab_data.slots[slot_index].tries_remaining -= 1; 568 569 if (save_metadata_if_changed(ops->ab_ops, &ab_data, &ab_data_orig)) { 570 printf("Can not save metadata\n"); 571 return -1; 572 } 573 574 return 0; 575 } 576 577 /* 578 * In android A/B system, there is no recovery partition, 579 * but in the linux system, we need the recovery to update system. 580 * This function is used to find firmware in recovery partition 581 * when enable CONFIG_ANDROID_AB. 582 */ 583 bool ab_can_find_recovery_part(void) 584 { 585 disk_partition_t part_info; 586 struct blk_desc *dev_desc; 587 int part_num; 588 589 dev_desc = rockchip_get_bootdev(); 590 if (!dev_desc) { 591 printf("%s: Could not find device\n", __func__); 592 return false; 593 } 594 595 part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_RECOVERY, 596 &part_info); 597 if (part_num < 0) 598 return false; 599 else 600 return true; 601 } 602