Commit 9540f6290691125db5d6e539b044a7d6bd4eff05

Authored by Ji Luo
1 parent 2917552369

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);