diff options
| -rw-r--r-- | Kconfig | 17 | ||||
| -rw-r--r-- | arch/arm/lib/crt0.S | 4 | ||||
| -rw-r--r-- | arch/arm/lib/relocate.S | 25 | ||||
| -rw-r--r-- | common/board_f.c | 2 |
4 files changed, 47 insertions, 1 deletions
@@ -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 |
