common: android: AVB support lz4 kernel

The key point is to get kernel compression type by:
bootm_parse_comp((void *)(ulong)hdr + hdr->page_size);

Because if hdr->kernel_address is set as decompress
address before this comment, android_image_get_kernel_addr()
would return error kernel offset, result in a wrong
compression type from android_image_parse_comp().

Tested successfully on RK3568 EVB board:
 - LZ4 Image + AVB full partition load
 - LZ4 Image + AVB separate load
 - LZ4 Image + none-AVB separate load
 - Image + AVB full partition load
 - Image + AVB separate load
 - Image + none-AVB separate load

Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
Change-Id: Ic5385843f036b52eb7a286b7194852accfb52225
This commit is contained in:
Joseph Chen 2020-12-29 16:54:19 +08:00 committed by Jianhong Chen
parent 1f5c7b6414
commit 791045ea0f
1 changed files with 32 additions and 30 deletions

View File

@ -682,29 +682,12 @@ static ulong android_image_get_comp_addr(struct andr_img_hdr *hdr, int comp)
return load_addr;
}
/*
* 'boot_android' cmd use "kernel_addr_r" as default load address !
* We update it according to compress type and "kernel_addr_c/r".
*/
int android_image_parse_comp(struct andr_img_hdr *hdr, ulong *load_addr)
{
ulong new_load_addr;
int comp;
comp = android_image_parse_kernel_comp(hdr);
env_set_ulong("os_comp", comp);
new_load_addr = android_image_get_comp_addr(hdr, comp);
if (new_load_addr != 0)
*load_addr = new_load_addr;
return comp;
}
void android_image_set_decomp(struct andr_img_hdr *hdr, int comp)
{
ulong kernel_addr_r;
env_set_ulong("os_comp", comp);
/* zImage handles decompress itself */
if (comp != IH_COMP_NONE && comp != IH_COMP_ZIMAGE) {
kernel_addr_r = env_get_ulong("kernel_addr_r", 16, 0x02080000);
@ -727,23 +710,38 @@ static int android_image_load_separate(struct andr_img_hdr *hdr,
int android_image_memcpy_separate(struct andr_img_hdr *hdr, ulong *load_addr)
{
ulong comp_addr = *load_addr;
ulong comp_addr;
int comp;
comp = android_image_parse_comp(hdr, &comp_addr);
if (comp_addr == (ulong)hdr)
comp = bootm_parse_comp((void *)(ulong)hdr + hdr->page_size);
comp_addr = android_image_get_comp_addr(hdr, comp);
/* non-compressed image: already in-place */
if ((ulong)hdr == *load_addr)
return 0;
/* compressed image */
if (comp_addr) {
*load_addr = comp_addr;
if ((ulong)hdr == comp_addr) /* already in-place */
return 0;
}
/*
* The most possible reason to arrive here is:
*
* VBoot=1 and AVB load full partition to a temp memory buffer, now we
* separate(memcpy) subimages from boot.img to where they should be.
*/
if (hdr->header_version < 3) {
if (android_image_separate(hdr, NULL, (void *)comp_addr, hdr))
if (android_image_separate(hdr, NULL, (void *)(*load_addr), hdr))
return -1;
} else {
if (android_image_separate_v3(hdr, NULL, (void *)comp_addr, hdr))
if (android_image_separate_v3(hdr, NULL, (void *)(*load_addr), hdr))
return -1;
}
*load_addr = comp_addr;
android_image_set_decomp((void *)comp_addr, comp);
android_image_set_decomp((void *)(*load_addr), comp);
return 0;
}
@ -753,6 +751,7 @@ long android_image_load(struct blk_desc *dev_desc,
unsigned long load_address,
unsigned long max_size) {
struct andr_img_hdr *hdr;
ulong comp_addr;
int comp, ret;
int blk_off;
@ -791,11 +790,14 @@ long android_image_load(struct blk_desc *dev_desc,
return -1;
}
/* Make kernel start address at load_address */
load_address -= hdr->page_size;
/* Changed to compressed address ? */
comp = bootm_parse_comp((void *)(ulong)hdr + hdr->page_size);
comp_addr = android_image_get_comp_addr(hdr, comp);
if (comp_addr)
load_address = comp_addr;
else
load_address -= hdr->page_size;
/* Let's load kernel now ! */
comp = android_image_parse_comp(hdr, &load_address);
ret = android_image_load_separate(hdr, part_info, (void *)load_address);
if (ret) {
printf("Failed to load android image\n");