[PATCH v2 6/6] common: Add an option to relocate on ram top

Ilias Apalodimas ilias.apalodimas at linaro.org
Thu Apr 16 07:59:42 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.

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.

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 this if you are certain all of the devices can DMA to high memory.
+
 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;
+	} 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 +365,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);
@@ -970,6 +983,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) && \
@@ -998,7 +1012,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