common: android: avb support load android image separate

Skip fdt and ramdisk relocation to save boot time.

Change-Id: I56fd2fca97fa7795024aa542f0a45d0512be01d4
Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
Joseph Chen 2019-05-14 19:39:19 +08:00 committed by Jianhong Chen
parent 89151b4aad
commit 503a892f5a
4 changed files with 129 additions and 126 deletions

View File

@ -659,9 +659,14 @@ static AvbSlotVerifyResult android_slot_verify(char *boot_partname,
load_address -= hdr->page_size; load_address -= hdr->page_size;
*android_load_address = load_address; *android_load_address = load_address;
#ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE
android_image_load_separate(hdr, NULL,
(void *)load_address, hdr);
#else
memcpy((uint8_t *)load_address, memcpy((uint8_t *)load_address,
slot_data[0]->loaded_partitions->data, slot_data[0]->loaded_partitions->data,
slot_data[0]->loaded_partitions->data_size); slot_data[0]->loaded_partitions->data_size);
#endif
} else { } else {
slot_set_unbootable(&ab_data.slots[slot_index_to_boot]); slot_set_unbootable(&ab_data.slots[slot_index_to_boot]);
} }
@ -951,17 +956,6 @@ static int load_android_image(struct blk_desc *dev_desc,
return 0; return 0;
} }
static bool avb_enabled;
void android_avb_set_enabled(bool enable)
{
avb_enabled = enable;
}
bool android_avb_is_enabled(void)
{
return avb_enabled;
}
int android_bootloader_boot_flow(struct blk_desc *dev_desc, int android_bootloader_boot_flow(struct blk_desc *dev_desc,
unsigned long load_address) unsigned long load_address)
{ {
@ -1100,7 +1094,6 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
if (vboot_flag) { if (vboot_flag) {
printf("SecureBoot enabled, AVB verify\n"); printf("SecureBoot enabled, AVB verify\n");
android_avb_set_enabled(true);
if (android_slot_verify(boot_partname, &load_address, if (android_slot_verify(boot_partname, &load_address,
slot_suffix)) slot_suffix))
return -1; return -1;
@ -1113,13 +1106,11 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
printf("SecureBoot disabled, AVB skip\n"); printf("SecureBoot disabled, AVB skip\n");
env_update("bootargs", env_update("bootargs",
"androidboot.verifiedbootstate=orange"); "androidboot.verifiedbootstate=orange");
android_avb_set_enabled(false);
if (load_android_image(dev_desc, boot_partname, if (load_android_image(dev_desc, boot_partname,
slot_suffix, &load_address)) slot_suffix, &load_address))
return -1; return -1;
} else { } else {
printf("SecureBoot enabled, AVB verify\n"); printf("SecureBoot enabled, AVB verify\n");
android_avb_set_enabled(true);
if (android_slot_verify(boot_partname, &load_address, if (android_slot_verify(boot_partname, &load_address,
slot_suffix)) slot_suffix))
return -1; return -1;

View File

@ -194,37 +194,28 @@ ulong android_image_get_kload(const struct andr_img_hdr *hdr)
int android_image_get_ramdisk(const struct andr_img_hdr *hdr, int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
ulong *rd_data, ulong *rd_len) ulong *rd_data, ulong *rd_len)
{ {
bool avb_enabled = false;
#ifdef CONFIG_ANDROID_BOOTLOADER
avb_enabled = android_avb_is_enabled();
#endif
if (!hdr->ramdisk_size) { if (!hdr->ramdisk_size) {
*rd_data = *rd_len = 0; *rd_data = *rd_len = 0;
return -1; return -1;
} }
/* /* We have load ramdisk at "ramdisk_addr_r" */
* We have load ramdisk at "ramdisk_addr_r" when android avb is #ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE
* disabled and CONFIG_ANDROID_BOOT_IMAGE_SEPARATE enabled. ulong ramdisk_addr_r;
*/
if (!avb_enabled && IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE_SEPARATE)) {
ulong ramdisk_addr_r;
ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0); ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0);
if (!ramdisk_addr_r) { if (!ramdisk_addr_r) {
printf("No Found Ramdisk Load Address.\n"); printf("No Found Ramdisk Load Address.\n");
return -1; return -1;
}
*rd_data = ramdisk_addr_r;
} else {
*rd_data = (unsigned long)hdr;
*rd_data += hdr->page_size;
*rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
} }
*rd_data = ramdisk_addr_r;
#else
*rd_data = (unsigned long)hdr;
*rd_data += hdr->page_size;
*rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
#endif
*rd_len = hdr->ramdisk_size; *rd_len = hdr->ramdisk_size;
printf("RAM disk load addr 0x%08lx size %u KiB\n", printf("RAM disk load addr 0x%08lx size %u KiB\n",
@ -236,40 +227,30 @@ int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
int android_image_get_fdt(const struct andr_img_hdr *hdr, int android_image_get_fdt(const struct andr_img_hdr *hdr,
ulong *rd_data) ulong *rd_data)
{ {
bool avb_enabled = false;
#ifdef CONFIG_ANDROID_BOOTLOADER
avb_enabled = android_avb_is_enabled();
#endif
if (!hdr->second_size) { if (!hdr->second_size) {
*rd_data = 0; *rd_data = 0;
return -1; return -1;
} }
/* /* We have load fdt at "fdt_addr_r" */
* We have load fdt at "fdt_addr_r" when android avb is #if defined(CONFIG_USING_KERNEL_DTB) || \
* disabled and CONFIG_ANDROID_BOOT_IMAGE_SEPARATE enabled; defined(CONFIG_ANDROID_BOOT_IMAGE_SEPARATE)
* or CONFIG_USING_KERNEL_DTB is enabled. ulong fdt_addr_r;
*/
if (IS_ENABLED(CONFIG_USING_KERNEL_DTB) ||
(!avb_enabled && IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE_SEPARATE))) {
ulong fdt_addr_r;
fdt_addr_r = env_get_ulong("fdt_addr_r", 16, 0); fdt_addr_r = env_get_ulong("fdt_addr_r", 16, 0);
if (!fdt_addr_r) { if (!fdt_addr_r) {
printf("No Found FDT Load Address.\n"); printf("No Found FDT Load Address.\n");
return -1; return -1;
}
*rd_data = fdt_addr_r;
} else {
*rd_data = (unsigned long)hdr;
*rd_data += hdr->page_size;
*rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
*rd_data += ALIGN(hdr->ramdisk_size, hdr->page_size);
} }
*rd_data = fdt_addr_r;
#else
*rd_data = (unsigned long)hdr;
*rd_data += hdr->page_size;
*rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
*rd_data += ALIGN(hdr->ramdisk_size, hdr->page_size);
#endif
printf("FDT load addr 0x%08x size %u KiB\n", printf("FDT load addr 0x%08x size %u KiB\n",
hdr->second_addr, DIV_ROUND_UP(hdr->second_size, 1024)); hdr->second_addr, DIV_ROUND_UP(hdr->second_size, 1024));
@ -277,53 +258,70 @@ int android_image_get_fdt(const struct andr_img_hdr *hdr,
} }
#ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE #ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE
static int android_image_load_separate(struct blk_desc *dev_desc, int android_image_load_separate(struct andr_img_hdr *hdr,
struct andr_img_hdr *hdr, const disk_partition_t *part,
const disk_partition_t *part, void *load_address, void *ram_src)
void *android_load_address)
{ {
struct blk_desc *dev_desc = rockchip_get_bootdev();
ulong fdt_addr_r = env_get_ulong("fdt_addr_r", 16, 0); ulong fdt_addr_r = env_get_ulong("fdt_addr_r", 16, 0);
char *fdt_high = env_get("fdt_high");
char *ramdisk_high = env_get("initrd_high");
ulong blk_start, blk_cnt, size; ulong blk_start, blk_cnt, size;
int ret, blk_read = 0; int ret, blk_read = 0;
ulong start;
if (hdr->kernel_size) { if (hdr->kernel_size) {
size = hdr->kernel_size + hdr->page_size; size = hdr->kernel_size + hdr->page_size;
blk_start = part->start;
blk_cnt = DIV_ROUND_UP(size, dev_desc->blksz); blk_cnt = DIV_ROUND_UP(size, dev_desc->blksz);
if (!sysmem_alloc_base(MEMBLK_ID_KERNEL, if (!sysmem_alloc_base(MEMBLK_ID_KERNEL,
(phys_addr_t)android_load_address, (phys_addr_t)load_address,
blk_cnt * dev_desc->blksz)) blk_cnt * dev_desc->blksz))
return -ENXIO; return -ENXIO;
ret = blk_dread(dev_desc, blk_start, if (ram_src) {
blk_cnt, android_load_address); start = (ulong)ram_src;
if (ret != blk_cnt) { memcpy((char *)load_address,
debug("%s: read kernel failed, ret=%d\n", (char *)start, hdr->kernel_size);
__func__, ret); } else {
return -1; blk_start = part->start;
ret = blk_dread(dev_desc, blk_start,
blk_cnt, load_address);
if (ret != blk_cnt) {
debug("%s: read kernel failed, ret=%d\n",
__func__, ret);
return -1;
}
blk_read += ret;
} }
blk_read += ret;
} }
if (hdr->ramdisk_size) { if (hdr->ramdisk_size) {
ulong ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0); ulong ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0);
size = hdr->page_size + ALIGN(hdr->kernel_size, hdr->page_size); size = hdr->page_size + ALIGN(hdr->kernel_size, hdr->page_size);
blk_start = part->start + DIV_ROUND_UP(size, dev_desc->blksz);
blk_cnt = DIV_ROUND_UP(hdr->ramdisk_size, dev_desc->blksz); blk_cnt = DIV_ROUND_UP(hdr->ramdisk_size, dev_desc->blksz);
if (!sysmem_alloc_base(MEMBLK_ID_RAMDISK, if (!sysmem_alloc_base(MEMBLK_ID_RAMDISK,
ramdisk_addr_r, ramdisk_addr_r,
blk_cnt * dev_desc->blksz)) blk_cnt * dev_desc->blksz))
return -ENXIO; return -ENXIO;
if (ram_src) {
ret = blk_dread(dev_desc, blk_start, start = (unsigned long)ram_src;
blk_cnt, (void *)ramdisk_addr_r); start += hdr->page_size;
if (ret != blk_cnt) { start += ALIGN(hdr->kernel_size, hdr->page_size);
debug("%s: read ramdisk failed, ret=%d\n", memcpy((char *)ramdisk_addr_r,
__func__, ret); (char *)start, hdr->ramdisk_size);
return -1; } else {
blk_start = part->start +
DIV_ROUND_UP(size, dev_desc->blksz);
ret = blk_dread(dev_desc, blk_start,
blk_cnt, (void *)ramdisk_addr_r);
if (ret != blk_cnt) {
debug("%s: read ramdisk failed, ret=%d\n",
__func__, ret);
return -1;
}
blk_read += ret;
} }
blk_read += ret;
} }
if ((gd->fdt_blob != (void *)fdt_addr_r) && hdr->second_size) { if ((gd->fdt_blob != (void *)fdt_addr_r) && hdr->second_size) {
@ -345,7 +343,6 @@ static int android_image_load_separate(struct blk_desc *dev_desc,
size = hdr->page_size + size = hdr->page_size +
ALIGN(hdr->kernel_size, hdr->page_size) + ALIGN(hdr->kernel_size, hdr->page_size) +
ALIGN(hdr->ramdisk_size, hdr->page_size); ALIGN(hdr->ramdisk_size, hdr->page_size);
blk_start = part->start + DIV_ROUND_UP(size, dev_desc->blksz);
blk_cnt = DIV_ROUND_UP(hdr->second_size, dev_desc->blksz); blk_cnt = DIV_ROUND_UP(hdr->second_size, dev_desc->blksz);
if (!sysmem_alloc_base(MEMBLK_ID_FDT_AOSP, if (!sysmem_alloc_base(MEMBLK_ID_FDT_AOSP,
fdt_addr_r, fdt_addr_r,
@ -353,16 +350,42 @@ static int android_image_load_separate(struct blk_desc *dev_desc,
CONFIG_SYS_FDT_PAD)) CONFIG_SYS_FDT_PAD))
return -ENXIO; return -ENXIO;
ret = blk_dread(dev_desc, blk_start, blk_cnt, (void *)fdt_addr_r); if (ram_src) {
if (ret != blk_cnt) { start = (unsigned long)ram_src;
debug("%s: read dtb failed, ret=%d\n", __func__, ret); start += hdr->page_size;
return -1; start += ALIGN(hdr->kernel_size, hdr->page_size);
} start += ALIGN(hdr->ramdisk_size, hdr->page_size);
memcpy((char *)fdt_addr_r,
(char *)start, hdr->second_size);
} else {
blk_start = part->start +
DIV_ROUND_UP(size, dev_desc->blksz);
ret = blk_dread(dev_desc, blk_start, blk_cnt,
(void *)fdt_addr_r);
if (ret != blk_cnt) {
debug("%s: read dtb failed, ret=%d\n",
__func__, ret);
return -1;
}
blk_read += blk_cnt; blk_read += blk_cnt;
}
#endif /* CONFIG_RKIMG_BOOTLOADER */ #endif /* CONFIG_RKIMG_BOOTLOADER */
} }
if (blk_read > 0 || ram_src) {
if (!fdt_high) {
env_set_hex("fdt_high", -1UL);
printf("Fdt ");
}
if (!ramdisk_high) {
env_set_hex("initrd_high", -1UL);
printf("Ramdisk ");
}
if (!fdt_high || !ramdisk_high)
printf("skip relocation\n");
}
return blk_read; return blk_read;
} }
#endif /* CONFIG_ANDROID_BOOT_IMAGE_SEPARATE */ #endif /* CONFIG_ANDROID_BOOT_IMAGE_SEPARATE */
@ -451,36 +474,17 @@ long android_image_load(struct blk_desc *dev_desc,
blk_cnt, load_address); blk_cnt, load_address);
#ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE #ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE
if (!android_avb_is_enabled()) { blk_read =
char *fdt_high = env_get("fdt_high"); android_image_load_separate(hdr, part_info, buf, NULL);
char *ramdisk_high = env_get("initrd_high"); #else
if (!sysmem_alloc_base(MEMBLK_ID_ANDROID,
(phys_addr_t)buf,
blk_cnt * part_info->blksz))
return -ENXIO;
blk_read = blk_read = blk_dread(dev_desc, part_info->start,
android_image_load_separate(dev_desc, hdr, blk_cnt, buf);
part_info, buf);
if (blk_read > 0) {
if (!fdt_high) {
env_set_hex("fdt_high", -1UL);
printf("Fdt ");
}
if (!ramdisk_high) {
env_set_hex("initrd_high", -1UL);
printf("Ramdisk ");
}
if (!fdt_high || !ramdisk_high)
printf("skip relocation\n");
}
} else
#endif #endif
{
if (!sysmem_alloc_base(MEMBLK_ID_ANDROID,
(phys_addr_t)buf,
blk_cnt * part_info->blksz))
return -ENXIO;
blk_read = blk_dread(dev_desc, part_info->start,
blk_cnt, buf);
}
} }
/* /*

View File

@ -94,10 +94,4 @@ char *android_str_append(char *base_name, char *slot_suffix);
*/ */
int android_fdt_overlay_apply(void *fdt_addr); int android_fdt_overlay_apply(void *fdt_addr);
/** android_avb_is_enabled- get avb enable state.
* *
* @return true on enabled, otherwise disabled;
*/
bool android_avb_is_enabled(void);
#endif /* __ANDROID_BOOTLOADER_H */ #endif /* __ANDROID_BOOTLOADER_H */

View File

@ -1274,6 +1274,20 @@ ulong android_image_get_end(const struct andr_img_hdr *hdr);
ulong android_image_get_kload(const struct andr_img_hdr *hdr); ulong android_image_get_kload(const struct andr_img_hdr *hdr);
void android_print_contents(const struct andr_img_hdr *hdr); void android_print_contents(const struct andr_img_hdr *hdr);
/** android_image_load_separate - Load an Android Image separate from storage or ram
*
* Load an Android Image based on the header size in the storage or ram.
*
* @hdr: The android image header
* @part: The partition where to read the image from
* @load_address: The address where the image will be loaded
* @ram_src: The ram source to load, if NULL load from partition
* @return the blk count.
*/
int android_image_load_separate(struct andr_img_hdr *hdr,
const disk_partition_t *part,
void *load_address, void *ram_src);
/** android_image_load - Load an Android Image from storage. /** android_image_load - Load an Android Image from storage.
* *
* Load an Android Image based on the header size in the storage. * Load an Android Image based on the header size in the storage.