[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