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;
*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,
slot_data[0]->loaded_partitions->data,
slot_data[0]->loaded_partitions->data_size);
#endif
} else {
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;
}
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,
unsigned long load_address)
{
@ -1100,7 +1094,6 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
if (vboot_flag) {
printf("SecureBoot enabled, AVB verify\n");
android_avb_set_enabled(true);
if (android_slot_verify(boot_partname, &load_address,
slot_suffix))
return -1;
@ -1113,13 +1106,11 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
printf("SecureBoot disabled, AVB skip\n");
env_update("bootargs",
"androidboot.verifiedbootstate=orange");
android_avb_set_enabled(false);
if (load_android_image(dev_desc, boot_partname,
slot_suffix, &load_address))
return -1;
} else {
printf("SecureBoot enabled, AVB verify\n");
android_avb_set_enabled(true);
if (android_slot_verify(boot_partname, &load_address,
slot_suffix))
return -1;

View File

@ -194,22 +194,13 @@ ulong android_image_get_kload(const struct andr_img_hdr *hdr)
int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
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) {
*rd_data = *rd_len = 0;
return -1;
}
/*
* We have load ramdisk at "ramdisk_addr_r" when android avb is
* disabled and CONFIG_ANDROID_BOOT_IMAGE_SEPARATE enabled.
*/
if (!avb_enabled && IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE_SEPARATE)) {
/* We have load ramdisk at "ramdisk_addr_r" */
#ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE
ulong ramdisk_addr_r;
ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0);
@ -219,11 +210,11 @@ int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
}
*rd_data = ramdisk_addr_r;
} else {
#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;
@ -236,24 +227,14 @@ int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
int android_image_get_fdt(const struct andr_img_hdr *hdr,
ulong *rd_data)
{
bool avb_enabled = false;
#ifdef CONFIG_ANDROID_BOOTLOADER
avb_enabled = android_avb_is_enabled();
#endif
if (!hdr->second_size) {
*rd_data = 0;
return -1;
}
/*
* We have load fdt at "fdt_addr_r" when android avb is
* disabled and CONFIG_ANDROID_BOOT_IMAGE_SEPARATE enabled;
* or CONFIG_USING_KERNEL_DTB is enabled.
*/
if (IS_ENABLED(CONFIG_USING_KERNEL_DTB) ||
(!avb_enabled && IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE_SEPARATE))) {
/* We have load fdt at "fdt_addr_r" */
#if defined(CONFIG_USING_KERNEL_DTB) || \
defined(CONFIG_ANDROID_BOOT_IMAGE_SEPARATE)
ulong fdt_addr_r;
fdt_addr_r = env_get_ulong("fdt_addr_r", 16, 0);
@ -263,12 +244,12 @@ int android_image_get_fdt(const struct andr_img_hdr *hdr,
}
*rd_data = fdt_addr_r;
} else {
#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",
hdr->second_addr, DIV_ROUND_UP(hdr->second_size, 1024));
@ -277,26 +258,34 @@ int android_image_get_fdt(const struct andr_img_hdr *hdr,
}
#ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE
static int android_image_load_separate(struct blk_desc *dev_desc,
struct andr_img_hdr *hdr,
int android_image_load_separate(struct andr_img_hdr *hdr,
const disk_partition_t *part,
void *android_load_address)
void *load_address, void *ram_src)
{
struct blk_desc *dev_desc = rockchip_get_bootdev();
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;
int ret, blk_read = 0;
ulong start;
if (hdr->kernel_size) {
size = hdr->kernel_size + hdr->page_size;
blk_start = part->start;
blk_cnt = DIV_ROUND_UP(size, dev_desc->blksz);
if (!sysmem_alloc_base(MEMBLK_ID_KERNEL,
(phys_addr_t)android_load_address,
(phys_addr_t)load_address,
blk_cnt * dev_desc->blksz))
return -ENXIO;
if (ram_src) {
start = (ulong)ram_src;
memcpy((char *)load_address,
(char *)start, hdr->kernel_size);
} else {
blk_start = part->start;
ret = blk_dread(dev_desc, blk_start,
blk_cnt, android_load_address);
blk_cnt, load_address);
if (ret != blk_cnt) {
debug("%s: read kernel failed, ret=%d\n",
__func__, ret);
@ -304,18 +293,26 @@ static int android_image_load_separate(struct blk_desc *dev_desc,
}
blk_read += ret;
}
}
if (hdr->ramdisk_size) {
ulong ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0);
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);
if (!sysmem_alloc_base(MEMBLK_ID_RAMDISK,
ramdisk_addr_r,
blk_cnt * dev_desc->blksz))
return -ENXIO;
if (ram_src) {
start = (unsigned long)ram_src;
start += hdr->page_size;
start += ALIGN(hdr->kernel_size, hdr->page_size);
memcpy((char *)ramdisk_addr_r,
(char *)start, hdr->ramdisk_size);
} 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) {
@ -325,6 +322,7 @@ static int android_image_load_separate(struct blk_desc *dev_desc,
}
blk_read += ret;
}
}
if ((gd->fdt_blob != (void *)fdt_addr_r) && hdr->second_size) {
#ifdef CONFIG_RKIMG_BOOTLOADER
@ -345,7 +343,6 @@ static int android_image_load_separate(struct blk_desc *dev_desc,
size = hdr->page_size +
ALIGN(hdr->kernel_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);
if (!sysmem_alloc_base(MEMBLK_ID_FDT_AOSP,
fdt_addr_r,
@ -353,16 +350,42 @@ static int android_image_load_separate(struct blk_desc *dev_desc,
CONFIG_SYS_FDT_PAD))
return -ENXIO;
ret = blk_dread(dev_desc, blk_start, blk_cnt, (void *)fdt_addr_r);
if (ram_src) {
start = (unsigned long)ram_src;
start += hdr->page_size;
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);
debug("%s: read dtb failed, ret=%d\n",
__func__, ret);
return -1;
}
blk_read += blk_cnt;
}
#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;
}
#endif /* CONFIG_ANDROID_BOOT_IMAGE_SEPARATE */
@ -451,28 +474,9 @@ long android_image_load(struct blk_desc *dev_desc,
blk_cnt, load_address);
#ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE
if (!android_avb_is_enabled()) {
char *fdt_high = env_get("fdt_high");
char *ramdisk_high = env_get("initrd_high");
blk_read =
android_image_load_separate(dev_desc, hdr,
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
{
android_image_load_separate(hdr, part_info, buf, NULL);
#else
if (!sysmem_alloc_base(MEMBLK_ID_ANDROID,
(phys_addr_t)buf,
blk_cnt * part_info->blksz))
@ -480,7 +484,7 @@ long android_image_load(struct blk_desc *dev_desc,
blk_read = blk_dread(dev_desc, part_info->start,
blk_cnt, buf);
}
#endif
}
/*

View File

@ -94,10 +94,4 @@ char *android_str_append(char *base_name, char *slot_suffix);
*/
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 */

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);
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.
*
* Load an Android Image based on the header size in the storage.