Commit 9540f6290691125db5d6e539b044a7d6bd4eff05
1 parent
2917552369
Exists in
smarc_8mq-imx_v2020.04_5.4.24_2.1.0
and in
1 other branch
MA-16203 Load boot/dtbo image to fixed memory
Only limited heap memory is available on imx8q platforms due to some memory is reserved for m4 image. Commit cd67414 will free avb verify data and thus help decrease the heap memory consumption. But when the device is locked, avb will try to verify one slot first, it will continue to verify another if the first slot returns failure. Function load_full_partition() will alloc memory to load boot/dtbo images from heap (which is a big and continuous memory region), this memory will be freed if the first slot returns verify failure. but because part of the continous memory region will be used in following verify process, even total available memory is enough, u-boot can't find a continous memory region to load the boot/dtbo image for another slot and will return error "Failed to allocate memory". Instead, this commit use fixed memory region start from 96MB offset of CONFIG_FASTBOOT_BUF_ADDR to load the boot/dtbo images. Test: slot verify and A/B slot switch. Change-Id: Ifc83bed5a6be37196c0fd109d942eaf9b07b6a74 Signed-off-by: Ji Luo <ji.luo@nxp.com> (cherry picked from commit d13752e831957fb84c71f8ca24fd1979d3605cde)
Showing 1 changed file with 26 additions and 8 deletions Side-by-side Diff
lib/libavb/avb_slot_verify.c
... | ... | @@ -28,7 +28,22 @@ |
28 | 28 | |
29 | 29 | /* Maximum size of a vbmeta image - 64 KiB. */ |
30 | 30 | #define VBMETA_MAX_SIZE (64 * 1024) |
31 | +/* Set the image load addr start from 96MB offset of CONFIG_FASTBOOT_BUF_ADDR */ | |
32 | +#define PARTITION_LOAD_ADDR_START (CONFIG_FASTBOOT_BUF_ADDR + (96 * 1024 * 1024)) | |
31 | 33 | |
34 | +/* Load dtbo/boot partition to fixed address instead of heap memory. */ | |
35 | +static void *image_addr_top = (void *)PARTITION_LOAD_ADDR_START; | |
36 | +static void *alloc_partition_addr(int size) | |
37 | +{ | |
38 | + void *ptr = image_addr_top; | |
39 | + image_addr_top = image_addr_top + ROUND(size, ARCH_DMA_MINALIGN); | |
40 | + return ptr; | |
41 | +} | |
42 | +static void free_partition_addr(int size) | |
43 | +{ | |
44 | + image_addr_top = (void *)(image_addr_top - ROUND(size, ARCH_DMA_MINALIGN)); | |
45 | +} | |
46 | + | |
32 | 47 | static AvbSlotVerifyResult initialize_persistent_digest( |
33 | 48 | AvbOps* ops, |
34 | 49 | const char* part_name, |
... | ... | @@ -101,7 +116,7 @@ |
101 | 116 | |
102 | 117 | /* Allocate and copy the partition. */ |
103 | 118 | if (!*out_image_preloaded) { |
104 | - *out_image_buf = avb_malloc(image_size); | |
119 | + *out_image_buf = (void *)alloc_partition_addr(image_size); | |
105 | 120 | if (*out_image_buf == NULL) { |
106 | 121 | return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
107 | 122 | } |
108 | 123 | |
... | ... | @@ -498,8 +513,10 @@ |
498 | 513 | } |
499 | 514 | |
500 | 515 | fail: |
516 | + /* Now the image_buf is not allocated by malloc(), we should not free. | |
517 | + * Instead, we should reset the image_addr_top.*/ | |
501 | 518 | if (image_buf != NULL && !image_preloaded) { |
502 | - avb_free(image_buf); | |
519 | + free_partition_addr(image_size); | |
503 | 520 | } |
504 | 521 | return ret; |
505 | 522 | } |
506 | 523 | |
... | ... | @@ -511,13 +528,13 @@ |
511 | 528 | AvbSlotVerifyData* slot_data) { |
512 | 529 | AvbSlotVerifyResult ret; |
513 | 530 | uint8_t* image_buf = NULL; |
531 | + uint64_t image_size; | |
514 | 532 | bool image_preloaded = false; |
515 | 533 | size_t n; |
516 | 534 | |
517 | 535 | for (n = 0; requested_partitions[n] != NULL; n++) { |
518 | 536 | char part_name[AVB_PART_NAME_MAX_SIZE]; |
519 | 537 | AvbIOResult io_ret; |
520 | - uint64_t image_size; | |
521 | 538 | AvbPartitionData* loaded_partition; |
522 | 539 | |
523 | 540 | if (!avb_str_concat(part_name, |
524 | 541 | |
... | ... | @@ -571,9 +588,10 @@ |
571 | 588 | ret = AVB_SLOT_VERIFY_RESULT_OK; |
572 | 589 | |
573 | 590 | out: |
574 | - /* Free the current buffer if any. */ | |
591 | + /* Now the image_buf is not allocated by malloc(), we should not free. | |
592 | + * Instead, we should reset the image_addr_top.*/ | |
575 | 593 | if (image_buf != NULL && !image_preloaded) { |
576 | - avb_free(image_buf); | |
594 | + free_partition_addr(image_size); | |
577 | 595 | } |
578 | 596 | /* Buffers that are already saved in slot_data will be handled by the caller |
579 | 597 | * even on failure. */ |
580 | 598 | |
... | ... | @@ -1678,10 +1696,10 @@ |
1678 | 1696 | if (loaded_partition->partition_name != NULL) { |
1679 | 1697 | avb_free(loaded_partition->partition_name); |
1680 | 1698 | } |
1681 | - if (loaded_partition->data != NULL && !loaded_partition->preloaded) { | |
1682 | - avb_free(loaded_partition->data); | |
1683 | - } | |
1684 | 1699 | } |
1700 | + /* partition data is not loaded to heap memory, so we just reset the | |
1701 | + * image_addr_top here. */ | |
1702 | + image_addr_top = (void *)PARTITION_LOAD_ADDR_START; | |
1685 | 1703 | avb_free(data->loaded_partitions); |
1686 | 1704 | } |
1687 | 1705 | avb_free(data); |