| Message ID | 20210802104457.31906-1-chiawei_wang@aspeedtech.com |
|---|---|
| State | Changes Requested |
| Delegated to: | Tom Rini |
| Headers | show |
| Series | armv7: Add Position Independent Execution support | expand |
On Mon, Aug 02, 2021 at 06:44:57PM +0800, Chia-Wei Wang wrote: > 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 could be loaded to any > SRAM/DRAM address on demands through ethernet/UART/etc. > > 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> > --- > arch/arm/Kconfig | 4 +++- > arch/arm/cpu/armv7/start.S | 43 ++++++++++++++++++++++++++++++++++++++ > arch/arm/lib/crt0.S | 11 ++++++++++ > arch/arm/lib/relocate.S | 35 ++++++++++++++++++++++--------- > 4 files changed, 82 insertions(+), 11 deletions(-) > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 2b7b625705..45879c9f06 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -9,7 +9,7 @@ config ARM64 > select PHYS_64BIT > select SYS_CACHE_SHIFT_6 > > -if ARM64 > +if ARM64 || CPU_V7A > config POSITION_INDEPENDENT > bool "Generate position-independent pre-relocation code" > help Thanks for doing this. I think we need to fix the depends on lines here rather than hide with if ARM64 || CPU_V7A, and then fix anything else that follows to also have the correct dependencies.
Hi Tom, > From: Tom Rini <trini@konsulko.com> > Sent: Tuesday, August 3, 2021 5:31 AM > On Mon, Aug 02, 2021 at 06:44:57PM +0800, Chia-Wei Wang wrote: > > 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 could be loaded to any SRAM/DRAM > > address on demands through ethernet/UART/etc. > > > > 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> > > --- > > arch/arm/Kconfig | 4 +++- > > arch/arm/cpu/armv7/start.S | 43 > ++++++++++++++++++++++++++++++++++++++ > > arch/arm/lib/crt0.S | 11 ++++++++++ > > arch/arm/lib/relocate.S | 35 ++++++++++++++++++++++--------- > > 4 files changed, 82 insertions(+), 11 deletions(-) > > > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index > > 2b7b625705..45879c9f06 100644 > > --- a/arch/arm/Kconfig > > +++ b/arch/arm/Kconfig > > @@ -9,7 +9,7 @@ config ARM64 > > select PHYS_64BIT > > select SYS_CACHE_SHIFT_6 > > > > -if ARM64 > > +if ARM64 || CPU_V7A > > config POSITION_INDEPENDENT > > bool "Generate position-independent pre-relocation code" > > help > > Thanks for doing this. I think we need to fix the depends on lines here rather > than hide with if ARM64 || CPU_V7A, and then fix anything else that follows to > also have the correct dependencies. Thanks for reviewing this. I will prepare a v2 patch to include the 'depends on' fix. Regards, Chiawei
On 2021/8/3 5:30, Tom Rini wrote: > On Mon, Aug 02, 2021 at 06:44:57PM +0800, Chia-Wei Wang wrote: >> 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 could be loaded to any >> SRAM/DRAM address on demands through ethernet/UART/etc. How? When flash got corrupted, how do you manage to load the golden image? >> >> 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> >> --- >> arch/arm/Kconfig | 4 +++- >> arch/arm/cpu/armv7/start.S | 43 ++++++++++++++++++++++++++++++++++++++ >> arch/arm/lib/crt0.S | 11 ++++++++++ >> arch/arm/lib/relocate.S | 35 ++++++++++++++++++++++--------- >> 4 files changed, 82 insertions(+), 11 deletions(-) >> >> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig >> index 2b7b625705..45879c9f06 100644 >> --- a/arch/arm/Kconfig >> +++ b/arch/arm/Kconfig >> @@ -9,7 +9,7 @@ config ARM64 >> select PHYS_64BIT >> select SYS_CACHE_SHIFT_6 >> >> -if ARM64 >> +if ARM64 || CPU_V7A >> config POSITION_INDEPENDENT >> bool "Generate position-independent pre-relocation code" >> help > > Thanks for doing this. I think we need to fix the depends on lines here > rather than hide with if ARM64 || CPU_V7A, and then fix anything else > that follows to also have the correct dependencies. >
Hi Peng, > -----Original Message----- > From: Peng Fan (OSS) <peng.fan@oss.nxp.com> > Sent: Tuesday, August 3, 2021 2:02 PM > > > On 2021/8/3 5:30, Tom Rini wrote: > > On Mon, Aug 02, 2021 at 06:44:57PM +0800, Chia-Wei Wang wrote: > >> 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 could be loaded to any > >> SRAM/DRAM address on demands through ethernet/UART/etc. > > How? When flash got corrupted, how do you manage to load the golden > image? AST2600 supports boot-from-UART through HW strap. When boot-from-UART is enabled for recovery purposes, the ROM code receives image data bytes from UART and put them into SRAM for execution. In addition, if secure boot is also enabled, the image sent has to be signed and be verified by the public key programmed in OTP. As AST2600 is based on ARMv7 architecture, this patch is implemented for. Regards, Chiawei > > >> > >> 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> > >> --- > >> arch/arm/Kconfig | 4 +++- > >> arch/arm/cpu/armv7/start.S | 43 > ++++++++++++++++++++++++++++++++++++++ > >> arch/arm/lib/crt0.S | 11 ++++++++++ > >> arch/arm/lib/relocate.S | 35 ++++++++++++++++++++++--------- > >> 4 files changed, 82 insertions(+), 11 deletions(-) > >> > >> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index > >> 2b7b625705..45879c9f06 100644 > >> --- a/arch/arm/Kconfig > >> +++ b/arch/arm/Kconfig > >> @@ -9,7 +9,7 @@ config ARM64 > >> select PHYS_64BIT > >> select SYS_CACHE_SHIFT_6 > >> > >> -if ARM64 > >> +if ARM64 || CPU_V7A > >> config POSITION_INDEPENDENT > >> bool "Generate position-independent pre-relocation code" > >> help > > > > Thanks for doing this. I think we need to fix the depends on lines > > here rather than hide with if ARM64 || CPU_V7A, and then fix anything > > else that follows to also have the correct dependencies. > >
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2b7b625705..45879c9f06 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -9,7 +9,7 @@ config ARM64 select PHYS_64BIT select SYS_CACHE_SHIFT_6 -if ARM64 +if ARM64 || CPU_V7A config POSITION_INDEPENDENT bool "Generate position-independent pre-relocation code" help @@ -19,7 +19,9 @@ config POSITION_INDEPENDENT almost any 4K aligned address. This logic relies on the relocation information that is embedded in the binary to support U-Boot relocating itself to the top-of-RAM later during execution. +endif +if ARM64 config INIT_SP_RELATIVE bool "Specify the early stack pointer relative to the .bss section" default n if ARCH_QEMU diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index dcb4195d7b..3c0b2d6a71 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 diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S index 46b6be21a8..956d258c9d 100644 --- a/arch/arm/lib/crt0.S +++ b/arch/arm/lib/crt0.S @@ -130,6 +130,14 @@ ENTRY(_main) ldr r9, [r9, #GD_NEW_GD] /* r9 <- gd->new_gd */ adr lr, here +#if defined(CONFIG_POSITION_INDEPENDENT) + adr r0, _main + ldr r1, _start_ofs + add r0, r1 + ldr r1, =CONFIG_SYS_TEXT_BASE + sub r1, r0 + add lr, r1 +#endif ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */ add lr, lr, r0 #if defined(CONFIG_CPU_V7M) @@ -180,3 +188,6 @@ here: #endif ENDPROC(_main) + +_start_ofs: + .word _start - _main diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S index e5f7267be1..14b7f61c1a 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -78,22 +78,28 @@ ENDPROC(relocate_vectors) */ ENTRY(relocate_code) - ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */ - subs r4, r0, r1 /* r4 <- relocation offset */ - beq relocate_done /* skip relocation */ - ldr r2, =__image_copy_end /* r2 <- SRC &__image_copy_end */ - + adr r3, relocate_code + ldr r1, _image_copy_start_ofs + add r1, r3 /* r1 <- Run &__image_copy_start */ + subs r4, r0, r1 /* r4 <- Run to copy offset */ + beq relocate_done /* skip relocation */ + ldr r1, _image_copy_start_ofs + add r1, r3 /* r1 <- Run &__image_copy_start */ + ldr r2, _image_copy_end_ofs + add r2, r3 /* r2 <- Run &__image_copy_end */ copy_loop: - ldmia r1!, {r10-r11} /* copy from source address [r1] */ - stmia r0!, {r10-r11} /* copy to target address [r0] */ - cmp r1, r2 /* until source end address [r2] */ + ldmia r1!, {r10-r11} /* copy from source address [r1] */ + stmia r0!, {r10-r11} /* copy to target address [r0] */ + cmp r1, r2 /* until source end address [r2] */ blo copy_loop /* * fix .rel.dyn relocations */ - ldr r2, =__rel_dyn_start /* r2 <- SRC &__rel_dyn_start */ - ldr r3, =__rel_dyn_end /* r3 <- SRC &__rel_dyn_end */ + ldr r1, _rel_dyn_start_ofs + add r2, r1, r3 /* r2 <- Run &__rel_dyn_start */ + ldr r1, _rel_dyn_end_ofs + add r3, r1, r3 /* r3 <- Run &__rel_dyn_end */ fixloop: ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */ and r1, r1, #0xff @@ -129,3 +135,12 @@ relocate_done: #endif ENDPROC(relocate_code) + +_image_copy_start_ofs: + .word __image_copy_start - relocate_code +_image_copy_end_ofs: + .word __image_copy_end - relocate_code +_rel_dyn_start_ofs: + .word __rel_dyn_start - relocate_code +_rel_dyn_end_ofs: + .word __rel_dyn_end - relocate_code
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 could be loaded to any SRAM/DRAM address on demands through ethernet/UART/etc. 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> --- arch/arm/Kconfig | 4 +++- arch/arm/cpu/armv7/start.S | 43 ++++++++++++++++++++++++++++++++++++++ arch/arm/lib/crt0.S | 11 ++++++++++ arch/arm/lib/relocate.S | 35 ++++++++++++++++++++++--------- 4 files changed, 82 insertions(+), 11 deletions(-)