From: Marek Vasut Date: Sun, 15 Mar 2026 23:54:05 +0000 (+0100) Subject: arm: relocate: Introduce data-only relocation mode X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d9eee3d17882ec40f8ca5e231046bbf287ab4369;p=thirdparty%2Fu-boot.git arm: relocate: Introduce data-only relocation mode 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 --- diff --git a/Kconfig b/Kconfig index b52331d6ff2..1679bba5d75 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 a90dcf3013c..11ad5779115 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -462,7 +462,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