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 <marek.vasut+renesas@mailbox.org>
This commit is contained in:
@@ -474,6 +474,23 @@ config SKIP_RELOCATE
|
|||||||
Skips relocation of U-Boot allowing for systems that have extremely
|
Skips relocation of U-Boot allowing for systems that have extremely
|
||||||
limited RAM to run U-Boot.
|
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
|
endif # EXPERT
|
||||||
|
|
||||||
config PHYS_64BIT
|
config PHYS_64BIT
|
||||||
|
|||||||
@@ -157,7 +157,11 @@ ENTRY(_main)
|
|||||||
orr lr, #1 /* As required by Thumb-only */
|
orr lr, #1 /* As required by Thumb-only */
|
||||||
#endif
|
#endif
|
||||||
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
|
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
|
||||||
|
#if defined(CONFIG_SKIP_RELOCATE_CODE)
|
||||||
|
bl relocate_code
|
||||||
|
#else
|
||||||
b relocate_code
|
b relocate_code
|
||||||
|
#endif
|
||||||
here:
|
here:
|
||||||
/*
|
/*
|
||||||
* now relocate vectors
|
* now relocate vectors
|
||||||
|
|||||||
@@ -79,6 +79,15 @@ ENDPROC(relocate_vectors)
|
|||||||
ENTRY(relocate_code)
|
ENTRY(relocate_code)
|
||||||
relocate_base:
|
relocate_base:
|
||||||
adr r3, 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
|
ldr r1, _image_copy_start_ofs
|
||||||
add r1, r3 /* r1 <- Run &__image_copy_start */
|
add r1, r3 /* r1 <- Run &__image_copy_start */
|
||||||
subs r4, r0, r1 /* r4 <- Run to copy offset */
|
subs r4, r0, r1 /* r4 <- Run to copy offset */
|
||||||
@@ -90,6 +99,7 @@ copy_loop:
|
|||||||
stmia r0!, {r10-r11} /* copy to target address [r0] */
|
stmia r0!, {r10-r11} /* copy to target address [r0] */
|
||||||
cmp r1, r2 /* until source end address [r2] */
|
cmp r1, r2 /* until source end address [r2] */
|
||||||
blo copy_loop
|
blo copy_loop
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fix .rel.dyn relocations
|
* fix .rel.dyn relocations
|
||||||
@@ -107,6 +117,15 @@ fixloop:
|
|||||||
/* relative fix: increase location by offset */
|
/* relative fix: increase location by offset */
|
||||||
add r0, r0, r4
|
add r0, r0, r4
|
||||||
ldr r1, [r0]
|
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
|
add r1, r1, r4
|
||||||
str r1, [r0]
|
str r1, [r0]
|
||||||
fixnext:
|
fixnext:
|
||||||
@@ -126,3 +145,9 @@ _rel_dyn_start_ofs:
|
|||||||
.word __rel_dyn_start - relocate_code
|
.word __rel_dyn_start - relocate_code
|
||||||
_rel_dyn_end_ofs:
|
_rel_dyn_end_ofs:
|
||||||
.word __rel_dyn_end - relocate_code
|
.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
|
||||||
|
|||||||
+1
-1
@@ -462,7 +462,7 @@ static int reserve_uboot(void)
|
|||||||
if (CONFIG_IS_ENABLED(SKIP_RELOCATE))
|
if (CONFIG_IS_ENABLED(SKIP_RELOCATE))
|
||||||
gd->flags |= GD_FLG_SKIP_RELOC;
|
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
|
* reserve memory for U-Boot code, data & bss
|
||||||
* round down to next 4 kB limit
|
* round down to next 4 kB limit
|
||||||
|
|||||||
Reference in New Issue
Block a user