[U-Boot] [PATCH][ELF RELOC] armv7, beagle: add support for ELF relocations
Steve Sakoman
sakoman at gmail.com
Thu Oct 21 06:57:01 CEST 2010
On Mon, Oct 11, 2010 at 5:08 AM, Heiko Schocher <hs at denx.de> wrote:
> Signed-off-by: Heiko Schocher <hs at denx.de>
> ---
> arch/arm/cpu/armv7/start.S | 131 ++++++++++++++++++++++++----------------
> arch/arm/cpu/armv7/u-boot.lds | 7 ++
> arch/arm/lib/cache.c | 2 +-
> include/configs/omap3_beagle.h | 2 +-
> 4 files changed, 87 insertions(+), 55 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> index c392c5d..d5c053d 100644
> --- a/arch/arm/cpu/armv7/start.S
> +++ b/arch/arm/cpu/armv7/start.S
> @@ -78,13 +78,13 @@ _armboot_start:
> /*
> * These are defined in the board-specific linker script.
> */
> -.globl _bss_start
> -_bss_start:
> - .word __bss_start
> +.globl _bss_start_ofs
> +_bss_start_ofs:
> + .word __bss_start - _start
>
> -.globl _bss_end
> -_bss_end:
> - .word _end
> +.globl _bss_end_ofs
> +_bss_end_ofs:
> + .word _end - _start
>
> #ifdef CONFIG_USE_IRQ
> /* IRQ stack memory (calculated at run-time) */
> @@ -104,29 +104,29 @@ FIQ_STACK_START:
> IRQ_STACK_START_IN:
> .word 0x0badc0de
>
> -.globl _datarel_start
> -_datarel_start:
> - .word __datarel_start
> +.globl _datarel_start_ofs
> +_datarel_start_ofs:
> + .word __datarel_start - _start
>
> -.globl _datarelrolocal_start
> -_datarelrolocal_start:
> - .word __datarelrolocal_start
> +.globl _datarelrolocal_start_ofs
> +_datarelrolocal_start_ofs:
> + .word __datarelrolocal_start - _start
>
> -.globl _datarellocal_start
> -_datarellocal_start:
> - .word __datarellocal_start
> +.globl _datarellocal_start_ofs
> +_datarellocal_start_ofs:
> + .word __datarellocal_start - _start
>
> -.globl _datarelro_start
> -_datarelro_start:
> - .word __datarelro_start
> +.globl _datarelro_start_ofs
> +_datarelro_start_ofs:
> + .word __datarelro_start - _start
>
> -.globl _got_start
> -_got_start:
> - .word __got_start
> +.globl _got_start_ofs
> +_got_start_ofs:
> + .word __got_start - _start
>
> -.globl _got_end
> -_got_end:
> - .word __got_end
> +.globl _got_end_Ofs
> +_got_end_ofs:
> + .word __got_end - _start
>
> /*
> * the actual reset code
> @@ -198,9 +198,8 @@ stack_setup:
> #ifndef CONFIG_SKIP_RELOCATE_UBOOT
> adr r0, _start
> ldr r2, _TEXT_BASE
> - ldr r3, _bss_start
> - sub r2, r3, r2 /* r2 <- size of armboot */
> - add r2, r0, r2 /* r2 <- source end address */
> + ldr r3, _bss_start_ofs
> + add r2, r0, r3 /* r2 <- source end address */
> cmp r0, r6
> #ifndef CONFIG_PRELOADER
> beq jump_2_ram
> @@ -213,33 +212,51 @@ copy_loop:
> blo copy_loop
>
> #ifndef CONFIG_PRELOADER
> - /* fix got entries */
> - ldr r1, _TEXT_BASE
> - mov r0, r7 /* reloc addr */
> - ldr r2, _got_start /* addr in Flash */
> - ldr r3, _got_end /* addr in Flash */
> - sub r3, r3, r1
> - add r3, r3, r0
> - sub r2, r2, r1
> - add r2, r2, r0
> -
> + /*
> + * fix .rel.dyn relocations
> + */
> + ldr r0, _TEXT_BASE /* r0 <- Text base */
> + sub r9, r7, r0 /* r9 <- relocation offset */
> + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
> + add r10, r10, r0 /* r10 <- sym table in FLASH */
> + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
> + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
> + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
> + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
> fixloop:
> - ldr r4, [r2]
> - sub r4, r4, r1
> - add r4, r4, r0
> - str r4, [r2]
> - add r2, r2, #4
> + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
> + add r0, r9 /* r0 <- location to fix up in RAM */
> + ldr r1, [r2, #4]
> + and r8, r1, #0xff
> + cmp r8, #23 /* relative fixup? */
> + beq fixrel
> + cmp r8, #2 /* absolute fixup? */
> + beq fixabs
> + /* ignore unknown type of fixup */
> + b fixnext
> +fixabs:
> + /* absolute fix: set location to (offset) symbol value */
> + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
> + add r1, r10, r1 /* r1 <- address of symbol in table */
> + ldr r1, [r1, #4] /* r1 <- symbol value */
> + add r1, r9 /* r1 <- relocated sym addr */
> + b fixnext
> +fixrel:
> + /* relative fix: increase location by offset */
> + ldr r1, [r0]
> + add r1, r1, r9
> +fixnext:
> + str r1, [r0]
> + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
> cmp r2, r3
> - bne fixloop
> + blo fixloop
>
> clear_bss:
> - ldr r0, _bss_start
> - ldr r1, _bss_end
> + ldr r0, _bss_start_ofs
> + ldr r1, _bss_end_ofs
> ldr r3, _TEXT_BASE /* Text base */
> mov r4, r7 /* reloc addr */
> - sub r0, r0, r3
> add r0, r0, r4
> - sub r1, r1, r3
> add r1, r1, r4
> mov r2, #0x00000000 /* clear */
>
> @@ -255,18 +272,26 @@ clbss_l:str r2, [r0] /* clear loop... */
> * initialization, now running from RAM.
> */
> jump_2_ram:
> - ldr r0, _TEXT_BASE
> - ldr r2, _board_init_r
> - sub r2, r2, r0
> - add r2, r2, r7 /* position from board_init_r in RAM */
> + ldr r0, _board_init_r_ofs
> + adr r1, _start
> + add r0, r0, r1
> + add lr, r0, r9
> /* setup parameters for board_init_r */
> mov r0, r5 /* gd_t */
> mov r1, r7 /* dest_addr */
> /* jump to it ... */
> - mov lr, r2
> mov pc, lr
>
> -_board_init_r: .word board_init_r
> +_board_init_r_ofs:
> + .word board_init_r - _start
> +
> +_rel_dyn_start_ofs:
> + .word __rel_dyn_start - _start
> +_rel_dyn_end_ofs:
> + .word __rel_dyn_end - _start
> +_dynsym_start_ofs:
> + .word __dynsym_start - _start
> +
> #else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
> /*
> * the actual reset code
> diff --git a/arch/arm/cpu/armv7/u-boot.lds b/arch/arm/cpu/armv7/u-boot.lds
> index d4fd3fc..88a0fec 100644
> --- a/arch/arm/cpu/armv7/u-boot.lds
> +++ b/arch/arm/cpu/armv7/u-boot.lds
> @@ -53,6 +53,13 @@ SECTIONS
> __datarelro_start = .;
> *(.data.rel.ro)
> }
> + . = ALIGN(4);
> + __rel_dyn_start = .;
> + .rel.dyn : { *(.rel.dyn) }
> + __rel_dyn_end = .;
> +
> + __dynsym_start = .;
> + .dynsym : { *(.dynsym) }
>
> __got_start = .;
> . = ALIGN(4);
> diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c
> index 55b633e..5715168 100644
> --- a/arch/arm/lib/cache.c
> +++ b/arch/arm/lib/cache.c
> @@ -38,7 +38,7 @@ void flush_cache (unsigned long dummy1, unsigned long dummy2)
> /* disable write buffer as well (page 2-22) */
> asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
> #endif
> -#ifdef CONFIG_ARMCORTEXA8
> +#ifdef CONFIG_ARMV7
This particular change breaks the build for OMAP4 boards since OMAP4
doesn't currently have a v7_flush_cache_all routine.
I suspect that this change may also break other non-OMAP ARMV7 boards,
since I only see a v7_flush_cache_all implementation for OMAP3.
I think it would probably be best to leave this define as is for now,
it can be changed when the other architectures provide
implementations, or when we discover that a shared implementation is
possible.
I'll do a bit more research tomorrow, but in looking at the TI
internal u-boot tree for OMAP4 there is the following commit:
ARM: OMAP4: Remove L2 Cache code.
OMAP4430 uses external L2 Cache
So it may not make sense for OMAP4.
Steve
> void v7_flush_cache_all(void);
>
> v7_flush_cache_all();
> diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
> index 2463be4..cf73f27 100644
> --- a/include/configs/omap3_beagle.h
> +++ b/include/configs/omap3_beagle.h
> @@ -341,7 +341,7 @@ extern unsigned int boot_flash_type;
> #endif
>
> /* additions for new relocation code, must added to all boards */
> -#undef CONFIG_SYS_ARM_WITHOUT_RELOC /* This board is tested with relocation support */
> +#define CONFIG_RELOC_FIXUP_WORKS
> #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
> #define CONFIG_SYS_INIT_SP_ADDR (LOW_LEVEL_SRAM_STACK - CONFIG_SYS_GBL_DATA_SIZE)
>
> --
> 1.7.2.3
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
More information about the U-Boot
mailing list