[PATCH v1 4/4] common: Add an optionto relocate on ram top
Ilias Apalodimas
ilias.apalodimas at linaro.org
Fri Apr 3 11:02:43 CEST 2026
On Fri, 3 Apr 2026 at 12:01, Ilias Apalodimas
<ilias.apalodimas at linaro.org> wrote:
>
> Right now we only relocate u-boot to the top of the first
> memory bank unless the board specific code overwrites it.
> This is problematic when loading big binaries as it
> fragments the contiguous memory space for no apparent reason.
>
> It's worth noting that there are cases where we must not relocate
> above the 4GiB boundary (64bit hardware with 32bit only capable
> DMA). E.g This will break platforms, if the ethernet
> controller cannot DMA above 4 GiB, and once U-Boot does
> get relocated above 4 GiB, the packet buffer which is built
> into the U-Boot binary is also relocated above 4 GiB.
>
> A previous patch moves the bi_dram[] info from bd to gd and make
> the memory bank information available early. So move the
> dram_init_banksize() INITCALL before the relocation address calculation
> and use it to derive the address.
>
> Also add a Kconfig option and allow the common code to relocate U-Boot
> to the top of the last discovered bank.
>
> Signed-off-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
> ---
> Kconfig | 8 ++++++++
> common/board_f.c | 17 ++++++++++++++++-
> 2 files changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/Kconfig b/Kconfig
> index ce25ea24a60f..b25e7f25591d 100644
> --- a/Kconfig
> +++ b/Kconfig
> @@ -474,6 +474,14 @@ config SKIP_RELOCATE
> Skips relocation of U-Boot allowing for systems that have extremely
> limited RAM to run U-Boot.
>
> +config RELOC_ADDR_TOP
> + bool "Relocate to the topmost memory address"
> + help
> + When U-Boot relocates, it chooses the end of the first memory bank.
> + Enable this if you have multiple banks and want U-Boot to relocate
> + to the topmost memory address. This will use the information of the
> + board memory banks configured with dram_init_banksize().
> +
> endif # EXPERT
>
> config PHYS_64BIT
> diff --git a/common/board_f.c b/common/board_f.c
> index dd5518b60db4..2eab344037c8 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -339,6 +339,10 @@ static int setup_ram_base(void)
>
> static int setup_ram_config(void)
> {
> +#if CONFIG_IS_ENABLED(RELOC_ADDR_TOP)
> + int bank;
> + phys_size_t total_size = 0;
> +#endif
> debug("Monitor len: %08x\n", gd->mon_len);
> #if CONFIG_VAL(SYS_MEM_TOP_HIDE)
> /*
> @@ -353,8 +357,19 @@ static int setup_ram_config(void)
> */
> gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
> #endif
And I just realized I forgot to amend one of my patches....
This blocks needs to move below if CONFIG_IS_ENABLED(RELOC_ADDR_TOP)
etc, but I'll fix it in V2
> +#if CONFIG_IS_ENABLED(RELOC_ADDR_TOP)
> + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
> + if (gd->ram_top <= gd->bi_dram[bank].start)
> + gd->ram_top = gd->bi_dram[bank].start +
> + gd->bi_dram[bank].size;
> + total_size += gd->bi_dram[bank].size;
> + }
> +
> + gd->ram_size = total_size;
> +#else
> gd->ram_top = gd->ram_base + get_effective_memsize();
> gd->ram_top = board_get_usable_ram_top(gd->mon_len);
> +#endif
>
> debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top);
> debug("Ram size: %08llX\n", (unsigned long long)gd->ram_size);
> @@ -971,6 +986,7 @@ static void initcall_run_f(void)
> * - board info struct
> */
> INITCALL(setup_ram_base);
> + INITCALL(dram_init_banksize);
> INITCALL(setup_ram_config);
> INITCALL(setup_dest_addr);
> #if CONFIG_IS_ENABLED(OF_BOARD_FIXUP) && \
> @@ -999,7 +1015,6 @@ static void initcall_run_f(void)
> INITCALL(reserve_bloblist);
> INITCALL(reserve_arch);
> INITCALL(reserve_stacks);
> - INITCALL(dram_init_banksize);
> INITCALL(show_dram_config);
> WATCHDOG_RESET();
> INITCALL(setup_bdinfo);
> --
> 2.53.0
>
More information about the U-Boot
mailing list