From cedcf38ffffed883de4c90f1465bed20678b6146 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 19 Nov 2023 07:43:31 -0700 Subject: [PATCH 1/4] image: Correct load_bug typo Correct a typo in the function comment for image_decomp(). Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- include/image.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/image.h b/include/image.h index 2e3cf839ee3..0fe67852c56 100644 --- a/include/image.h +++ b/include/image.h @@ -936,7 +936,7 @@ int image_decomp_type(const unsigned char *buf, ulong len); * @load: Destination load address in U-Boot memory * @image_start Image start address (where we are decompressing from) * @type: OS type (IH_OS_...) - * @load_bug: Place to decompress to + * @load_buf: Place to decompress to * @image_buf: Address to decompress from * @image_len: Number of bytes in @image_buf to decompress * @unc_len: Available space for decompression From 30ad6366c0eef6dd7d8753e2d58d0bb5fe944a3a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 19 Nov 2023 07:43:32 -0700 Subject: [PATCH 2/4] image: Show the load address when decompressing The destination address for decompression (or copying) is useful information. Show this to the user while booting, e.g.: Uncompressing Kernel Image (no loading done) to 2080000 Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/image.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/boot/image.c b/boot/image.c index 88b67bc3a19..675b5dd77f9 100644 --- a/boot/image.c +++ b/boot/image.c @@ -415,15 +415,20 @@ void image_print_contents(const void *ptr) * @type: OS type (IH_OS_...) * @comp_type: Compression type being used (IH_COMP_...) * @is_xip: true if the load address matches the image start + * @load: Load address for printing */ -static void print_decomp_msg(int comp_type, int type, bool is_xip) +static void print_decomp_msg(int comp_type, int type, bool is_xip, + ulong load) { const char *name = genimg_get_type_name(type); + /* Shows "Loading Kernel Image" for example */ if (comp_type == IH_COMP_NONE) - printf(" %s %s\n", is_xip ? "XIP" : "Loading", name); + printf(" %s %s", is_xip ? "XIP" : "Loading", name); else - printf(" Uncompressing %s\n", name); + printf(" Uncompressing %s", name); + + printf(" to %lx\n", load); } int image_decomp_type(const unsigned char *buf, ulong len) @@ -448,7 +453,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, int ret = -ENOSYS; *load_end = load; - print_decomp_msg(comp, type, load == image_start); + print_decomp_msg(comp, type, load == image_start, load); /* * Load the image to the right place, decompressing if needed. After From bb07cdb19194bd141f7c3c631eddd4bfaf651e4d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 19 Nov 2023 07:43:33 -0700 Subject: [PATCH 3/4] bootm: Move arm64-image processing later If the image is compressed, then the existing check fails, since the header is wrong. Move the check later in the boot process, after the kernel is decompressed. This allows use of bootm with compressed kernels, while still permitting an uncompressed kernel to be used. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/boot/bootm.c b/boot/bootm.c index cb61485c226..e051a0cc188 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -240,24 +240,8 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, } if (images.os.type == IH_TYPE_KERNEL_NOLOAD) { - if (IS_ENABLED(CONFIG_CMD_BOOTI) && - images.os.arch == IH_ARCH_ARM64 && - images.os.os == IH_OS_LINUX) { - ulong image_addr; - ulong image_size; - - ret = booti_setup(images.os.image_start, &image_addr, - &image_size, true); - if (ret != 0) - return 1; - - images.os.type = IH_TYPE_KERNEL; - images.os.load = image_addr; - images.ep = image_addr; - } else { - images.os.load = images.os.image_start; - images.ep += images.os.image_start; - } + images.os.load = images.os.image_start; + images.ep += images.os.image_start; } images.os.start = map_to_sysmem(os_hdr); @@ -466,6 +450,31 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) } } + if (IS_ENABLED(CONFIG_CMD_BOOTI) && images->os.arch == IH_ARCH_ARM64 && + images->os.os == IH_OS_LINUX) { + ulong relocated_addr; + ulong image_size; + int ret; + + ret = booti_setup(load, &relocated_addr, &image_size, false); + if (ret) { + printf("Failed to prep arm64 kernel (err=%d)\n", ret); + return BOOTM_ERR_RESET; + } + + /* Handle BOOTM_STATE_LOADOS */ + if (relocated_addr != load) { + printf("Moving Image from 0x%lx to 0x%lx, end=%lx\n", + load, relocated_addr, + relocated_addr + image_size); + memmove((void *)relocated_addr, load_buf, image_size); + } + + images->ep = relocated_addr; + images->os.start = relocated_addr; + images->os.end = relocated_addr + image_size; + } + lmb_reserve(&images->lmb, images->os.load, (load_end - images->os.load)); return 0; From 69544c4fd8b1e77e00403e9a6cba7e2d7bb3ff68 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 19 Nov 2023 07:43:34 -0700 Subject: [PATCH 4/4] bootm: Support kernel_noload with compression It is not currently possible to execute the kernel in-place without loading it. Use lmb to allocate memory for it. Co-developed-by: Tom Rini Signed-off-by: Simon Glass Suggested-by: Tom Rini Signed-off-by: Tom Rini --- boot/bootm.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/boot/bootm.c b/boot/bootm.c index e051a0cc188..7c1b4a34c4c 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -410,6 +410,24 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) void *load_buf, *image_buf; int err; + /* + * For a "noload" compressed kernel we need to allocate a buffer large + * enough to decompress in to and use that as the load address now. + * Assume that the kernel compression is at most a factor of 4 since + * zstd almost achieves that. + * Use an alignment of 2MB since this might help arm64 + */ + if (os.type == IH_TYPE_KERNEL_NOLOAD && os.comp != IH_COMP_NONE) { + ulong req_size = ALIGN(image_len * 4, SZ_1M); + + load = lmb_alloc(&images->lmb, req_size, SZ_2M); + if (!load) + return 1; + os.load = load; + debug("Allocated %lx bytes at %lx for kernel (size %lx) decompression\n", + req_size, load, image_len); + } + load_buf = map_sysmem(load, 0); image_buf = map_sysmem(os.image_start, image_len); err = image_decomp(os.comp, load, os.image_start, os.type,