]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
arm: relocate: Introduce data-only relocation mode
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Sun, 15 Mar 2026 23:54:05 +0000 (00:54 +0100)
committerTom Rini <trini@konsulko.com>
Fri, 27 Mar 2026 19:29:31 +0000 (13:29 -0600)
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@mailbox.org>
Kconfig
arch/arm/lib/crt0.S
arch/arm/lib/relocate.S
common/board_f.c

diff --git a/Kconfig b/Kconfig
index b52331d6ff25ad3e5f43707719f78c3a5daa2090..1679bba5d7500baaf202d22bbff96bd859678928 100644 (file)
--- 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
index d10c129705d0eb77bb0e2855b4984e685673985d..f2c5aa37a8f26d2d13ce87df864ebaab9f77eca8 100644 (file)
@@ -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
index 6ee58f4edfe8e702196e8a5c5a900b1bdb105b14..b6a648708f4a9cd08c4ad0f8b0dfef99dd629d40 100644 (file)
@@ -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
index a90dcf3013cd1e1dfa4453ce80d77f101de6d4f8..11ad57791155689113e2b417e17dbd2b9ac3af9f 100644 (file)
@@ -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