diff mbox

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

Message ID 1319464779-23571-1-git-send-email-swarren@nvidia.com
State Changes Requested
Headers show

Commit Message

Stephen Warren Oct. 24, 2011, 1:59 p.m. UTC
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@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(-)

Comments

Simon Glass Oct. 26, 2011, midnight UTC | #1
Hi Stephen,

On Mon, Oct 24, 2011 at 6:59 AM, Stephen Warren <swarren@nvidia.com> wrote:
> 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@nvidia.com>

How do I test this one, please?

Regards,
Simon

> ---
> 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
>
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
Stephen Warren Oct. 26, 2011, 6:37 a.m. UTC | #2
Simon Glass wrote at Tuesday, October 25, 2011 6:01 PM:
> On Mon, Oct 24, 2011 at 6:59 AM, Stephen Warren <swarren@nvidia.com> wrote:
> > 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@nvidia.com>
> 
> How do I test this one, please?

When running mkimage, specify -1 or 0xffffffff as the load address, and
0 as the entry point (zImages have code right at the beginning of the
image).

Then, for various arbitrary ${loadaddr}, do e.g.:

ext2load ${devtype} ${devnum}:${rootpart} ${loadaddr} /boot/vmlinux.uimg
bootm ${loadaddr}

It should work for any ${loadaddr} (providing the ext2load doesn't
over-write U-Boot!)
Marek Vasut Oct. 31, 2011, 6:36 p.m. UTC | #3
> 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@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
> 

[...]

This one doesn't apply on top of current u-boot master
Simon Glass Oct. 31, 2011, 6:49 p.m. UTC | #4
Hi Marek,

On Mon, Oct 31, 2011 at 11:36 AM, Marek Vasut <marek.vasut@gmail.com> wrote:
>> 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@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
>>
>
> [...]
>
> This one doesn't apply on top of current u-boot master

You need to revert Stephen's clean-up patch 1/2 712fbcf to test this.

Regards,
Simon

> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
Simon Glass Oct. 31, 2011, 9:20 p.m. UTC | #5
On Mon, Oct 24, 2011 at 6:59 AM, Stephen Warren <swarren@nvidia.com> wrote:
> 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@nvidia.com>

Tested-by: Simon Glass <sjg@chromium.org>

> ---
> 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 mbox

Patch

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);