From 791045ea0f80ba1bcca19898377c2a04c85444cc Mon Sep 17 00:00:00 2001 From: Joseph Chen Date: Tue, 29 Dec 2020 16:54:19 +0800 Subject: [PATCH] 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 Change-Id: Ic5385843f036b52eb7a286b7194852accfb52225 --- common/image-android.c | 62 ++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/common/image-android.c b/common/image-android.c index d141964672..57d46994a4 100644 --- a/common/image-android.c +++ b/common/image-android.c @@ -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");