From 27badbeb3b47c1151cc4d4eab3675ee839b5f716 Mon Sep 17 00:00:00 2001 From: Ji Luo Date: Tue, 13 Apr 2021 13:03:57 +0800 Subject: [PATCH] MA-18913 Load dtb according to kernel address As the kernel image will get bigger after enabling some debug tools, 64MB kernel max size is not enough. Load the dtb to the address right after linux kernel instead of setting fixed offset to the start of kernel image. The "kernel_size" in boot image header is the physical size of "Image" instead of the memory size which the linux requires to boot. Test: boots on imx8mp/imx8qm. Change-Id: I5946c8530610ff0742f2a911aaeccf7636938b94 Signed-off-by: Ji Luo Reviewed-by: Wang Haoran (cherry picked from commit c1f83790077516a64397467fce5880be0871f615) --- common/image-android.c | 29 ++++++++++++++++++ drivers/fastboot/fb_fsl/fb_fsl_boot.c | 44 ++++++++++++++++++--------- include/image.h | 2 ++ 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/common/image-android.c b/common/image-android.c index 83ed2f043b..fb32c9482c 100644 --- a/common/image-android.c +++ b/common/image-android.c @@ -801,3 +801,32 @@ bool image_arm64(void *images) return true; return false; } + +uint32_t kernel_size(void *images) +{ + struct header_image *ih; + uint32_t image_size; + + ih = (struct header_image *)images; + image_size = le64_to_cpu(ih->image_size); + + return image_size; +} + +ulong kernel_relocate_addr(ulong images) +{ + struct header_image *ih; + ulong relocated_addr, text_offset; + + ih = (struct header_image *)images; + text_offset = le64_to_cpu(ih->text_offset); + + if (le64_to_cpu(ih->res1) & BIT(3)) + relocated_addr = images - text_offset; + else + relocated_addr = gd->bd->bi_dram[0].start; + + relocated_addr = ALIGN(relocated_addr, SZ_2M) + text_offset; + + return relocated_addr; +} diff --git a/drivers/fastboot/fb_fsl/fb_fsl_boot.c b/drivers/fastboot/fb_fsl/fb_fsl_boot.c index b1df91999f..500d6f09e2 100644 --- a/drivers/fastboot/fb_fsl/fb_fsl_boot.c +++ b/drivers/fastboot/fb_fsl/fb_fsl_boot.c @@ -45,13 +45,8 @@ #include "fb_fsl_common.h" -/* max kernel image size */ -#ifdef CONFIG_ARCH_IMX8 -/* imx8q has more limitation so we assign less memory here. */ -#define MAX_KERNEL_LEN (60 * 1024 * 1024) -#else -#define MAX_KERNEL_LEN (64 * 1024 * 1024) -#endif +/* max kernel image size, used for compressed kernel image */ +#define MAX_KERNEL_LEN (96 * 1024 * 1024) /* Offset (in u32's) of start and end fields in the zImage header. */ #define ZIMAGE_START_ADDR 10 @@ -559,6 +554,7 @@ int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr = 0; u32 avb_metric; + u32 kernel_image_size = 0; bool check_image_arm64 = false; bool is_recovery_mode = false; bool gki_is_supported = false; @@ -737,6 +733,8 @@ int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { printf("Wrong kernel image! Please check if you need to enable 'CONFIG_LZ4'\n"); goto fail; } + + kernel_image_size = kernel_size((void *)((ulong)hdr_v3 + 4096)); } else { #if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) if (image_arm64((void *)((ulong)hdr + hdr->page_size))) { @@ -753,6 +751,8 @@ int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { printf("Wrong kernel image! Please check if you need to enable 'CONFIG_LZ4'\n"); goto fail; } + + kernel_image_size = kernel_size((void *)((ulong)hdr + hdr->page_size)); #else /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ /* copy kernel image and boot header to hdr->kernel_addr - hdr->page_size */ memcpy((void *)(ulong)(hdr->kernel_addr - hdr->page_size), (void *)hdr, @@ -785,15 +785,31 @@ int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #endif } + /* Check arm64 image */ + if (gki_is_supported) + check_image_arm64 = image_arm64((void *)(ulong)vendor_boot_hdr->kernel_addr); + else + check_image_arm64 = image_arm64((void *)(ulong)hdr->kernel_addr); + /* Start loading the dtb file */ u32 fdt_addr = 0; u32 fdt_size = 0; struct dt_table_header *dt_img = NULL; - if (gki_is_supported) - fdt_addr = (ulong)((ulong)(vendor_boot_hdr->kernel_addr) + MAX_KERNEL_LEN); - else - fdt_addr = (ulong)((ulong)(hdr->kernel_addr) + MAX_KERNEL_LEN); + /* Kernel addr may need relocatition, put the dtb right after the kernel image. */ + if (check_image_arm64) { + ulong relocated_addr; + + if (gki_is_supported) + relocated_addr = kernel_relocate_addr((ulong)(vendor_boot_hdr->kernel_addr)); + else + relocated_addr = kernel_relocate_addr((ulong)(hdr->kernel_addr)); + + fdt_addr = relocated_addr + kernel_image_size + 1024; /* 1K gap */ + } else { + /* Let's reserve 64 MB for arm32 case */ + fdt_addr = (ulong)((ulong)(hdr->kernel_addr) + 64 * 1024 * 1024); + } #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT /* It means boot.img(recovery) do not include dtb, it need load dtb from partition */ @@ -840,21 +856,19 @@ int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { /* Combine cmdline and Print image info */ if (gki_is_supported) { - check_image_arm64 = image_arm64((void *)(ulong)vendor_boot_hdr->kernel_addr); android_image_get_kernel_v3(hdr_v3, vendor_boot_hdr); addr = vendor_boot_hdr->kernel_addr; - printf("kernel @ %08x (%d)\n", vendor_boot_hdr->kernel_addr, hdr_v3->kernel_size); + printf("kernel @ %08x (%d)\n", vendor_boot_hdr->kernel_addr, kernel_image_size); printf("ramdisk @ %08x (%d)\n", vendor_boot_hdr->ramdisk_addr, vendor_boot_hdr->vendor_ramdisk_size + hdr_v3->ramdisk_size); } else { - check_image_arm64 = image_arm64((void *)(ulong)hdr->kernel_addr); if (check_image_arm64) { android_image_get_kernel(hdr, 0, NULL, NULL); addr = hdr->kernel_addr; } else { addr = (ulong)(hdr->kernel_addr - hdr->page_size); } - printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); + printf("kernel @ %08x (%d)\n", hdr->kernel_addr, kernel_image_size); printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); } if (fdt_size) diff --git a/include/image.h b/include/image.h index 3b0d896a0e..7ad42d7184 100644 --- a/include/image.h +++ b/include/image.h @@ -1544,6 +1544,8 @@ void android_print_contents(const struct andr_img_hdr *hdr); bool android_image_print_dtb_contents(ulong hdr_addr); #endif bool image_arm64(void *images); +uint32_t kernel_size(void *images); +ulong kernel_relocate_addr(ulong images); #endif /* CONFIG_ANDROID_BOOT_IMAGE */ #endif /* !USE_HOSTCC */ -- 2.17.1