[PATCH v2 4/4] common: Allow relocations on the top of the last bank

Ilias Apalodimas ilias.apalodimas at linaro.org
Tue Mar 31 10:01:14 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.

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          |  7 +++++++
 common/board_f.c | 15 +++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/Kconfig b/Kconfig
index ce25ea24a60f..3ebdee1b2794 100644
--- a/Kconfig
+++ b/Kconfig
@@ -474,6 +474,13 @@ config SKIP_RELOCATE
 	  Skips relocation of U-Boot allowing for systems that have extremely
 	  limited RAM to run U-Boot.
 
+config RELOCATE_LAST_BANK
+	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
+
 endif # EXPERT
 
 config PHYS_64BIT
diff --git a/common/board_f.c b/common/board_f.c
index df2b0dc899bf..4270f368e653 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -309,6 +309,8 @@ __weak int mach_cpu_init(void)
 /* Get the top of usable RAM */
 __weak phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
 {
+	int ret;
+
 #if defined(CFG_SYS_SDRAM_BASE) && CFG_SYS_SDRAM_BASE > 0
 	/*
 	 * Detect whether we have so much RAM that it goes past the end of our
@@ -321,6 +323,19 @@ __weak phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
 		 */
 		return 0;
 #endif
+	if (IS_ENABLED(CONFIG_RELOCATE_LAST_BANK)) {
+		phys_addr_t old_top = gd->ram_top;
+
+		ret = fdtdec_setup_mem_ram_top();
+		if (ret)
+			debug("failed to relocate to ram top");
+		ret = fdtdec_setup_ram_size();
+		if (ret) {
+			debug("failed to calculate RAM size");
+			gd->ram_top = old_top;
+		}
+	}
+
 	return gd->ram_top;
 }
 
-- 
2.53.0



More information about the U-Boot mailing list