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

Stephen Warren
2011-11-01T16:28:22Z

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.

disabled:

text data bss dec hex filename
166727 3568 217024 387319 5e8f7 ./u-boot

enabled:

text data bss dec hex filename
166819 3568 217020 387407 5e94f ./u-boot

v2: image_get_fdt(): Call image_fixup_load_entry() before
image_print_contents(). Rebased on ToT. Now fully tested on kernel,
initrd, and FDT uImages; previous version was only tested with kernel.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
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 c05c40a..8e2728c 100644
--- a/README
+++ b/README
@@ -3263,6 +3263,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 d301332..9b3bb9f 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -737,6 +737,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 7ce5d33..c12cfc2 100644
--- a/common/image.c
+++ b/common/image.c
@@ -344,6 +344,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
/**
@@ -381,6 +400,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);

@@ -1141,6 +1164,10 @@ static const image_header_t *image_get_fdt(ulong fdt_addr)
return NULL;
}

+#ifdef CONFIG_SYS_RELOCATABLE_IMAGES
+ image_fixup_load_entry((image_header_t *)fdt_hdr);
+#endif
+
image_print_contents(fdt_hdr);

puts(" Verifying Checksum ... ");
diff --git a/include/image.h b/include/image.h
index c56a18d..b2c1117 100644
--- a/include/image.h
+++ b/include/image.h
@@ -334,6 +334,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.0.4