[U-Boot] [PATCH RFC] common/image: Allow initrd_high & fdt_high to have special case no_reloc

The documented way of disabling relocation of the initrd or FDT is setting initrd_high or fdt_high to 0xffffffff. However, that is actually wrong on 64-bit platforms, where 0xffffffffffffffff needs to be used. This is somewhat painful:
- Some platforms (e.g. Raspberry Pi) have a common file setting fdt_high or initrd_high to 0xffffffff that is included in both 32-bit builds (RPi 1, 2) and 64-bit builds (RPi 3). Those are currently not doing the right thing in 64-bit builds, and it wouldn't be nice to #ifdef around that. - Typing the 16 consecutive f's in 0xffffffffffffffff is not very pleasant.
To fix these, make the initrd_high and fdt_high handling accept a special value "no_reloc" that does the right thing independent of the bitness. The old values keep working for compatibility.
Signed-off-by: Tuomas Tynkkynen tuomas@tuxera.com --- Only compile-tested so far.
README | 18 +++++++++++------- common/image-fdt.c | 2 +- common/image.c | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/README b/README index 7e0dd35f93..e5e10e46ca 100644 --- a/README +++ b/README @@ -4940,12 +4940,14 @@ List of environment variables (most likely not complete): of the 704 MB low memory, so that Linux kernel can access it during the boot procedure.
- If this is set to the special value 0xFFFFFFFF then - the fdt will not be copied at all on boot. For this - to work it must reside in writable memory, have - sufficient padding on the end of it for u-boot to - add the information it needs into it, and the memory - must be accessible by the kernel. + If this is set to "no_reloc" or to the largest + possible address (0xFFFFFFFF on 32-bit platforms, + 0xFFFFFFFFFFFFFFFF on 64-bit platforms), the fdt + will not be copied at all on boot. For this to work + it must reside in writable memory, have sufficient + padding on the end of it for u-boot to add the + information it needs into it, and the memory must + be accessible by the kernel.
fdtcontroladdr- if set this is the address of the control flattened device tree used by U-Boot when CONFIG_OF_CONTROL is @@ -4978,7 +4980,9 @@ List of environment variables (most likely not complete):
setenv initrd_high 00c00000
- If you set initrd_high to 0xFFFFFFFF, this is an + If you set initrd_high to "no_reloc" or to the largest + possible address (0xFFFFFFFF on 32-bit platforms, + 0xFFFFFFFFFFFFFFFF on 64-bit platforms), this is an indication to U-Boot that all addresses are legal for the Linux kernel, including addresses in flash memory. In this case U-Boot will NOT COPY the diff --git a/common/image-fdt.c b/common/image-fdt.c index e7540be8d6..3e3113b51c 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -136,7 +136,7 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) if (fdt_high) { void *desired_addr = (void *)simple_strtoul(fdt_high, NULL, 16);
- if (((ulong) desired_addr) == ~0UL) { + if (((ulong) desired_addr) == ~0UL || !strcmp(fdt_high, "no_reloc")) { /* All ones means use fdt in place */ of_start = fdt_blob; lmb_reserve(lmb, (ulong)of_start, of_len); diff --git a/common/image.c b/common/image.c index 8c35327745..35c67856c5 100644 --- a/common/image.c +++ b/common/image.c @@ -1229,7 +1229,7 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, * turning the "load high" feature off. This is intentional. */ initrd_high = simple_strtoul(s, NULL, 16); - if (initrd_high == ~0) + if (initrd_high == ~0 || !strcmp(s, "no_reloc")) initrd_copy_to_ram = 0; } else { initrd_high = getenv_bootm_mapsize() + getenv_bootm_low();

On Wed, Jan 18, 2017 at 02:50:28AM +0200, Tuomas Tynkkynen wrote:
The documented way of disabling relocation of the initrd or FDT is setting initrd_high or fdt_high to 0xffffffff. However, that is actually wrong on 64-bit platforms, where 0xffffffffffffffff needs to be used. This is somewhat painful:
- Some platforms (e.g. Raspberry Pi) have a common file setting fdt_high or initrd_high to 0xffffffff that is included in both 32-bit builds (RPi 1, 2) and 64-bit builds (RPi 3). Those are currently not doing the right thing in 64-bit builds, and it wouldn't be nice to #ifdef around that.
- Typing the 16 consecutive f's in 0xffffffffffffffff is not very pleasant.
To fix these, make the initrd_high and fdt_high handling accept a special value "no_reloc" that does the right thing independent of the bitness. The old values keep working for compatibility.
Signed-off-by: Tuomas Tynkkynen tuomas@tuxera.com
I don't like this, in concept. The general answer is that one should not set initrd_high / fdt_high to disabled. In specific and optimized cases where one knows that there is no potential for overlap one would load parts to the desired location and disable relocation. But in general I'm going to quote myself from include/configs/ti_armv7_common.h: /* * We setup defaults based on constraints from the Linux kernel, which should * also be safe elsewhere. We have the default load at 32MB into DDR (for * the kernel), FDT above 128MB (the maximum location for the end of the * kernel), and the ramdisk 512KB above that (allowing for hopefully never * seen large trees). We say all of this must be within the first 256MB * as that will normally be within the kernel lowmem and thus visible via * bootm_size and we only run on platforms with 256MB or more of memory. */
The problem I have with disabling relocation is how often I've seen people run into the problem of big kernel / big initrd / big fdt stomping over one of the other parts of the system (most often kernel BSS runs over whatever followed the kernel).
participants (2)
-
Tom Rini
-
Tuomas Tynkkynen