[PATCH] arm: relocate: Introduce data-only relocation mode

Marek Vasut marek.vasut+renesas at mailbox.org
Mon Mar 16 00:54:05 CET 2026


Introduce new mode of relocation which relocates only data, not code.
This is mainly meant to relocate data to read-write portion of the RAM,
while the code remains in read-only portion of the RAM from which it is
allowed to execute. This split configuration is present on various secure
cores.

The result of the relocation is U-Boot running at its original address,
data relocated to the end of DRAM, but with added read-write area offset.
The U-Boot binary area is not reserved from the end of the DRAM in this
relocation mode, because U-Boot itself is not relocated.

Signed-off-by: Marek Vasut <marek.vasut+renesas at mailbox.org>
---
Cc: Casey Connolly <casey.connolly at linaro.org>
Cc: Heiko Schocher <hs at nabladev.com>
Cc: Heinrich Schuchardt <xypron.glpk at gmx.de>
Cc: Jerome Forissier <jerome.forissier at arm.com> <jerome at forissier.org>
Cc: Jesse Taube <mr.bossman075 at gmail.com>
Cc: Peng Fan <peng.fan at nxp.com>
Cc: Quentin Schulz <quentin.schulz at cherry.de>
Cc: Simon Glass <sjg at chromium.org>
Cc: Tom Rini <trini at konsulko.com>
Cc: Udit Kumar <u-kumar1 at ti.com>
Cc: u-boot at lists.denx.de
---
 Kconfig                 | 17 +++++++++++++++++
 arch/arm/lib/crt0.S     |  4 ++++
 arch/arm/lib/relocate.S | 25 +++++++++++++++++++++++++
 common/board_f.c        |  2 +-
 4 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/Kconfig b/Kconfig
index ce25ea24a60..575ee3b574f 100644
--- a/Kconfig
+++ b/Kconfig
@@ -474,6 +474,23 @@ config SKIP_RELOCATE
 	  Skips relocation of U-Boot allowing for systems that have extremely
 	  limited RAM to run U-Boot.
 
+config SKIP_RELOCATE_CODE
+	bool "Skips relocation of U-Boot code to end of RAM"
+	help
+	  Skips relocation of U-Boot code to the end of RAM, but still does
+	  relocate data to the end of RAM. This is mainly meant to relocate
+	  data to read-write portion of the RAM, while the code remains in
+	  read-only portion of the RAM from which it is allowed to execute.
+	  This split configuration is present on various secure cores.
+
+config SKIP_RELOCATE_CODE_DATA_OFFSET
+	hex "Offset of read-write data memory from read-only text memory"
+	default 0x0
+	depends on SKIP_RELOCATE_CODE
+	help
+	  Offset of the read-write memory which contains data, from read-only
+	  memory which contains executable text.
+
 endif # EXPERT
 
 config PHYS_64BIT
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
index d10c129705d..f2c5aa37a8f 100644
--- a/arch/arm/lib/crt0.S
+++ b/arch/arm/lib/crt0.S
@@ -157,7 +157,11 @@ ENTRY(_main)
 	orr	lr, #1				/* As required by Thumb-only */
 #endif
 	ldr	r0, [r9, #GD_RELOCADDR]		/* r0 = gd->relocaddr */
+#if defined(CONFIG_SKIP_RELOCATE_CODE)
+	bl	relocate_code
+#else
 	b	relocate_code
+#endif
 here:
 /*
  * now relocate vectors
diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S
index 6ee58f4edfe..b6a648708f4 100644
--- a/arch/arm/lib/relocate.S
+++ b/arch/arm/lib/relocate.S
@@ -79,6 +79,15 @@ ENDPROC(relocate_vectors)
 ENTRY(relocate_code)
 relocate_base:
 	adr	r3, relocate_base
+
+#ifdef CONFIG_SKIP_RELOCATE_CODE
+	mov r4,	#CONFIG_SKIP_RELOCATE_CODE_DATA_OFFSET
+
+	ldr	r1, _data_start_ofs
+	add	r5, r1, r3		/* r5 <- Run &__data_start */
+	ldr	r1, _data_end_ofs
+	add	r6, r1, r3		/* r6 <- Run &__data_end */
+#else
 	ldr	r1, _image_copy_start_ofs
 	add	r1, r3			/* r1 <- Run &__image_copy_start */
 	subs	r4, r0, r1		/* r4 <- Run to copy offset      */
@@ -90,6 +99,7 @@ copy_loop:
 	stmia	r0!, {r10-r11}		/* copy to   target address [r0] */
 	cmp	r1, r2			/* until source end address [r2] */
 	blo	copy_loop
+#endif
 
 	/*
 	 * fix .rel.dyn relocations
@@ -107,6 +117,15 @@ fixloop:
 	/* relative fix: increase location by offset */
 	add	r0, r0, r4
 	ldr	r1, [r0]
+
+#ifdef CONFIG_SKIP_RELOCATE_CODE
+	/* Test whether this is data, if not, do not relocate. */
+	cmp	r1, r5
+	blt	fixnext
+	cmp	r1, r6
+	bgt	fixnext
+#endif
+
 	add	r1, r1, r4
 	str	r1, [r0]
 fixnext:
@@ -126,3 +145,9 @@ _rel_dyn_start_ofs:
 	.word	__rel_dyn_start - relocate_code
 _rel_dyn_end_ofs:
 	.word	__rel_dyn_end - relocate_code
+#ifdef CONFIG_SKIP_RELOCATE_CODE
+_data_start_ofs:
+	.word	__data_start - relocate_code
+_data_end_ofs:
+	.word	__data_end - relocate_code
+#endif
diff --git a/common/board_f.c b/common/board_f.c
index df2b0dc899b..bd45669aef5 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -463,7 +463,7 @@ static int reserve_uboot(void)
 	if (CONFIG_IS_ENABLED(SKIP_RELOCATE))
 		gd->flags |= GD_FLG_SKIP_RELOC;
 
-	if (!(gd->flags & GD_FLG_SKIP_RELOC)) {
+	if (!(gd->flags & GD_FLG_SKIP_RELOC) && !CONFIG_IS_ENABLED(SKIP_RELOCATE_CODE)) {
 		/*
 		 * reserve memory for U-Boot code, data & bss
 		 * round down to next 4 kB limit
-- 
2.51.0



More information about the U-Boot mailing list