[U-Boot] [PATCH] image: Allow images to indicate they're loadable at any address

Stephen Warren swarren at nvidia.com
Mon Oct 24 15:59:39 CEST 2011


The legacy uImage format includes an absolute load and entry-
point address. When presented with a uImage in memory that
isn't loaded at the address in the image's load address,
U-Boot will relocate the image to its address in the header.

Some payloads can actually be loaded and used at any arbitrary
address. An example is an ARM Linux kernel zImage file. This
is useful when sharing a single zImage across multiple boards
with different memory layouts, or U-Boot builds with different
${load_addr} since sharing a single absolute load address may
not be possible.

With this config option enabled, an image header may contain a
load address of -1/0xffffffff. This indicates the image can
operate at any load address, and U-Boot will avoid automtically
copying it anywhere. In this case, the entry-point field is
specified relative to the start of the image payload.

Signed-off-by: Stephen Warren <swarren at nvidia.com>
---
Wolfgang, 

This is an much simpler and less invasive alternative to my previous
IH_TYPE_KERNEL_REL patch. If it's OK, you can ignore that patch.

u-boot.bin sizes for Tegra Seaboard without/with this config option on:

   text	   data	    bss	    dec	    hex	filename
 165858	   3565	 217016	 386439	  5e587	./u-boot

with:

   text	   data	    bss	    dec	    hex	filename
 165950	   3565	 217012	 386527	  5e5df	./u-boot

 README             |   23 +++++++++++++++++++++++
 common/cmd_bootm.c |    4 ++++
 common/image.c     |   27 +++++++++++++++++++++++++++
 include/image.h    |    4 ++++
 4 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/README b/README
index eb9ade9..480cfe3 100644
--- a/README
+++ b/README
@@ -3177,6 +3177,29 @@ Low Level (hardware related) configuration options:
 		be used if available. These functions may be faster under some
 		conditions but may increase the binary size.
 
+Image-related options:
+---------------------------------------------------
+
+- CONFIG_SYS_RELOCATABLE_IMAGES
+
+		The legacy uImage format includes an absolute load and entry-
+		point address. When presented with a uImage in memory that
+		isn't loaded at the address in the image's load address,
+		U-Boot will relocate the image to its address in the header.
+
+		Some payloads can actually be loaded and used at any arbitrary
+		address. An example is an ARM Linux kernel zImage file. This
+		is useful when sharing a single zImage across multiple boards
+		with different memory layouts, or U-Boot builds with different
+		${load_addr} since sharing a single absolute load address may
+		not be possible.
+
+		With this config option enabled, an image header may contain a
+		load address of -1/0xffffffff. This indicates the image can
+		operate at any load address, and U-Boot will avoid automtically
+		copying it anywhere. In this case, the entry-point field is
+		specified relative to the start of the image payload.
+
 Building the Software:
 ======================
 
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index bb9b698..de08bbc 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -730,6 +730,10 @@ static image_header_t *image_get_kernel (ulong img_addr, int verify)
 		return NULL;
 	}
 
+#ifdef CONFIG_SYS_RELOCATABLE_IMAGES
+	image_fixup_load_entry(hdr);
+#endif
+
 	show_boot_progress (3);
 	image_print_contents (hdr);
 
diff --git a/common/image.c b/common/image.c
index 32ad4da..a746c6f 100644
--- a/common/image.c
+++ b/common/image.c
@@ -342,6 +342,25 @@ void image_print_contents (const void *ptr)
 	}
 }
 
+#ifdef CONFIG_SYS_RELOCATABLE_IMAGES
+void image_fixup_load_entry(image_header_t *hdr)
+{
+	ulong load;
+	ulong hsize;
+	ulong ep;
+
+	load = image_get_load(hdr);
+	if (load != -1)
+		return;
+
+	load = (ulong)hdr;
+	hsize = image_get_header_size();
+	ep = load + hsize + image_get_ep(hdr);
+
+	image_set_load(hdr, load);
+	image_set_ep(hdr, ep);
+}
+#endif
 
 #ifndef USE_HOSTCC
 /**
@@ -379,6 +398,10 @@ static const image_header_t *image_get_ramdisk (ulong rd_addr, uint8_t arch,
 		return NULL;
 	}
 
+#ifdef CONFIG_SYS_RELOCATABLE_IMAGES
+	image_fixup_load_entry((image_header_t *)rd_hdr);
+#endif
+
 	show_boot_progress (10);
 	image_print_contents (rd_hdr);
 
@@ -1116,6 +1139,10 @@ static const image_header_t *image_get_fdt (ulong fdt_addr)
 	}
 	puts ("OK\n");
 
+#ifdef CONFIG_SYS_RELOCATABLE_IMAGES
+	image_fixup_load_entry((image_header_t *)fdt_hdr);
+#endif
+
 	if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) {
 		fdt_error ("uImage is not a fdt");
 		return NULL;
diff --git a/include/image.h b/include/image.h
index b7caaa6..c680f1f 100644
--- a/include/image.h
+++ b/include/image.h
@@ -332,6 +332,10 @@ int genimg_get_format (void *img_addr);
 int genimg_has_config (bootm_headers_t *images);
 ulong genimg_get_image (ulong img_addr);
 
+#ifdef CONFIG_SYS_RELOCATABLE_IMAGES
+void image_fixup_load_entry(image_header_t *hdr);
+#endif
+
 int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images,
 		uint8_t arch, ulong *rd_start, ulong *rd_end);
 
-- 
1.7.4.1



More information about the U-Boot mailing list