diff options
author | Chia-Wei Wang <chiawei_wang@aspeedtech.com> | 2021-08-03 10:50:10 +0800 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-09-02 09:48:20 -0400 |
commit | cd82f199852d88218e1f17f5ec07cdd9112a89c4 (patch) | |
tree | f69d3b9a4abc0505567961380bd69929e5570318 /arch/arm/cpu/armv7 | |
parent | aa29b21d62d298fadcfbc8e36d8d248fbb24b52d (diff) | |
download | u-boot-cd82f199852d88218e1f17f5ec07cdd9112a89c4.tar.gz |
armv7: Add Position Independent Execution support
A U-Boot image could be loaded and executed at a different
location than it was linked at.
For example, Aspeed takes a stable release version of U-Boot image
as the golden one for recovery purposes. When the primary storage
such as flash is corrupted, the golden image would be loaded to any
SRAM/DRAM address on demands through ethernet/UART/etc and run for
rescue.
To deal with this condition, the PIE is needed as there is only one
signed, golden image, which could be however executed at different
places.
This patch adds the PIE support for ARMv7 platform.
Signed-off-by: Chia-Wei Wang <chiawei_wang@aspeedtech.com>
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r-- | arch/arm/cpu/armv7/start.S | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 87329d26e1..698e15b8e1 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -39,6 +39,42 @@ reset: /* Allow the board to save important registers */ b save_boot_params save_boot_params_ret: +#ifdef CONFIG_POSITION_INDEPENDENT + /* + * Fix .rela.dyn relocations. This allows U-Boot to loaded to and + * executed at a different address than it was linked at. + */ +pie_fixup: + adr r0, reset /* r0 <- Runtime value of reset label */ + ldr r1, =reset /* r1 <- Linked value of reset label */ + subs r4, r0, r1 /* r4 <- Runtime-vs-link offset */ + beq pie_fixup_done + + adr r0, pie_fixup + ldr r1, _rel_dyn_start_ofs + add r2, r0, r1 /* r2 <- Runtime &__rel_dyn_start */ + ldr r1, _rel_dyn_end_ofs + add r3, r0, r1 /* r3 <- Runtime &__rel_dyn_end */ + +pie_fix_loop: + ldr r0, [r2] /* r0 <- Link location */ + ldr r1, [r2, #4] /* r1 <- fixup */ + cmp r1, #23 /* relative fixup? */ + bne pie_skip_reloc + + /* relative fix: increase location by offset */ + add r0, r4 + ldr r1, [r0] + add r1, r4 + str r1, [r0] + str r0, [r2] + add r2, #8 +pie_skip_reloc: + cmp r2, r3 + blo pie_fix_loop +pie_fixup_done: +#endif + #ifdef CONFIG_ARMV7_LPAE /* * check for Hypervisor support @@ -340,3 +376,10 @@ ENTRY(cpu_init_crit) b lowlevel_init @ go setup pll,mux,memory ENDPROC(cpu_init_crit) #endif + +#if CONFIG_POSITION_INDEPENDENT +_rel_dyn_start_ofs: + .word __rel_dyn_start - pie_fixup +_rel_dyn_end_ofs: + .word __rel_dyn_end - pie_fixup +#endif |