[PATCH v2 6/6] common: Add an option to relocate on ram top
Marek Vasut
marek.vasut at mailbox.org
Sun Apr 26 18:35:05 CEST 2026
On 4/16/26 7:59 AM, Ilias Apalodimas 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.
On certain platforms, it is currently not possible to relocate U-Boot
above the 32bit boundary, due to various dependencies on content located
below the 32bit boundary. One such example is ethernet, where the packet
buffer built into U-Boot binary is placed below the 32bit boundary and
allows loading of data via ethernet even above 32bit boundary due to
memory copy from the packet buffer to the destination location.
> 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.
>
> Reviewed-by: Anshul Dalal <anshuld at ti.com>
> Tested-by: Anshul Dalal <anshuld at ti.com>
> Signed-off-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
> ---
> Kconfig | 10 ++++++++++
> common/board_f.c | 25 +++++++++++++++++++------
> 2 files changed, 29 insertions(+), 6 deletions(-)
>
> diff --git a/Kconfig b/Kconfig
> index 7f00e76ba786..63c273ca8c8f 100644
> --- a/Kconfig
> +++ b/Kconfig
> @@ -491,6 +491,16 @@ config SKIP_RELOCATE_CODE_DATA_OFFSET
> Offset of the read-write memory which contains data, from read-only
> memory which contains executable text.
>
> +config RELOC_ADDR_TOP
> + bool "Relocate to the topmost memory address"
> + depends on EXPERT
> + 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().
... use the information ... to do what ?
> + Use this if you are certain all of the devices can DMA to high memory.
... can access memory above the 32bit boundary.
> +
> endif # EXPERT
>
> config PHYS_64BIT
> diff --git a/common/board_f.c b/common/board_f.c
> index 4ac22dca9e7c..f95e789257ad 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -339,7 +339,22 @@ static int setup_ram_base(void)
> static int setup_ram_config(void)
> {
> debug("Monitor len: %08x\n", gd->mon_len);
> -#if CONFIG_VAL(SYS_MEM_TOP_HIDE)
> +
> + if (CONFIG_IS_ENABLED(RELOC_ADDR_TOP)) {
> + int bank;
> + phys_size_t total_size = 0;
> +
> + 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;
Shouldn't this also apply board_get_usable_ram_top() to be consistent ?
> + } else {
> + gd->ram_top = gd->ram_base + get_effective_memsize();
> + gd->ram_top = board_get_usable_ram_top(gd->mon_len);
Should this really use gd->mon_len as a parameter, or gd->ram_top?
[...]
More information about the U-Boot
mailing list