[PATCH v3 6/6] common: Add an option to relocate on ram top
Ilias Apalodimas
ilias.apalodimas at linaro.org
Mon Apr 27 12:08:27 CEST 2026
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.
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.
Signed-off-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
---
Kconfig | 12 ++++++++++++
common/board_f.c | 32 ++++++++++++++++++++++++++------
2 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/Kconfig b/Kconfig
index d1a042a11658..522eedf726ef 100644
--- a/Kconfig
+++ b/Kconfig
@@ -503,6 +503,18 @@ 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() to calculate
+ the relocation address.
+ Use this if you are certain all of the devices 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 f58061026f8f..c88f4d2f97a5 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -31,6 +31,7 @@
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
+#include <memtop.h>
#include <os.h>
#include <post.h>
#include <relocate.h>
@@ -339,7 +340,28 @@ 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;
+ phys_addr_t top;
+
+ for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
+ if (gd->ram_top <= gd->dram[bank].start)
+ gd->ram_top = gd->dram[bank].start +
+ gd->dram[bank].size;
+ total_size += gd->dram[bank].size;
+ }
+ gd->ram_size = total_size;
+
+ top = get_mem_top(gd->ram_base, gd->ram_size, 0, (void *)gd->fdt_blob);
+ if (top)
+ gd->ram_top = top;
+
+ } else {
+ gd->ram_top = gd->ram_base + get_effective_memsize();
+ gd->ram_top = board_get_usable_ram_top(gd->mon_len);
+ }
/*
* Subtract specified amount of memory to hide so that it won't
* get "touched" at all by U-Boot. By fixing up gd->ram_size
@@ -350,10 +372,8 @@ static int setup_ram_config(void)
* memory size from the SDRAM controller setup will have to
* get fixed.
*/
- gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
-#endif
- gd->ram_top = gd->ram_base + get_effective_memsize();
- gd->ram_top = board_get_usable_ram_top(gd->mon_len);
+ if (CONFIG_IS_ENABLED(SYS_MEM_TOP_HIDE))
+ gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
debug("Ram top: %08llx\n", (unsigned long long)gd->ram_top);
debug("Ram size: %08llx\n", (unsigned long long)gd->ram_size);
@@ -979,6 +999,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) && \
@@ -1007,7 +1028,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