]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'elf_reloc'
authorWolfgang Denk <wd@denx.de>
Tue, 19 Oct 2010 19:07:52 +0000 (21:07 +0200)
committerWolfgang Denk <wd@denx.de>
Tue, 19 Oct 2010 19:07:52 +0000 (21:07 +0200)
Conflicts:
arch/arm/include/asm/config.h
board/LaCie/edminiv2/config.mk
board/karo/tx25/config.mk
board/logicpd/imx27lite/config.mk
doc/README.arm-relocation

Signed-off-by: Wolfgang Denk <wd@denx.de>
1  2 
arch/arm/cpu/arm1136/start.S
arch/arm/cpu/arm926ejs/start.S
arch/arm/cpu/armv7/start.S
arch/arm/include/asm/config.h
arch/arm/lib/board.c
board/LaCie/edminiv2/config.mk
board/karo/tx25/config.mk
board/logicpd/imx27lite/config.mk
doc/README.arm-relocation

index 5008ac6e9e2f1a139d306e75122f3c8a91a021e6,a86114b81bbccff645dddb269c3dca6dd63d4656..29ed065c011f8d3c972d2ad6ed8733c89de85c27
@@@ -87,50 -87,37 +87,37 @@@ _end_vect
  
  .globl _TEXT_BASE
  _TEXT_BASE:
 -      .word   TEXT_BASE
 +      .word   CONFIG_SYS_TEXT_BASE
  
- #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
- .globl _armboot_start
- _armboot_start:
-       .word _start
- #endif
  /*
   * These are defined in the board-specific linker script.
+  * Subtracting _start from them lets the linker put their
+  * relative position in the executable instead of leaving
+  * them null.
   */
- .globl _bss_start
- _bss_start:
-       .word __bss_start
- .globl _bss_end
- _bss_end:
-       .word _end
- #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
- .globl _datarel_start
- _datarel_start:
-       .word __datarel_start
+ .globl _bss_start_ofs
+ _bss_start_ofs:
+       .word __bss_start - _start
  
- .globl _datarelrolocal_start
- _datarelrolocal_start:
-       .word __datarelrolocal_start
+ .globl _bss_end_ofs
+ _bss_end_ofs:
+       .word _end - _start
  
- .globl _datarellocal_start
- _datarellocal_start:
-       .word __datarellocal_start
+ .globl _datarel_start_ofs
+ _datarel_start_ofs:
+       .word __datarel_start - _start
  
- .globl _datarelro_start
- _datarelro_start:
-       .word __datarelro_start
+ .globl _datarelrolocal_start_ofs
+ _datarelrolocal_start_ofs:
+       .word __datarelrolocal_start - _start
  
- .globl _got_start
- _got_start:
-       .word __got_start
+ .globl _datarellocal_start_ofs
+ _datarellocal_start_ofs:
+       .word __datarellocal_start - _start
  
- .globl _got_end
- _got_end:
-       .word __got_end
- #endif
+ .globl _datarelro_start_ofs
+ _datarelro_start_ofs:
+       .word __datarelro_start - _start
  
  #ifdef CONFIG_USE_IRQ
  /* IRQ stack memory (calculated at run-time) */
@@@ -225,9 -212,8 +212,8 @@@ stack_setup
  
        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
        beq     clear_bss
  
@@@ -239,36 -225,54 +225,54 @@@ 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
+       ble     fixloop
  #endif
  #endif        /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
  
  clear_bss:
  #ifndef CONFIG_PRELOADER
-       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                            */
  
@@@ -283,24 -287,34 +287,34 @@@ clbss_l:str     r2, [r0]                /* clear loop..
   * initialization, now running from RAM.
   */
  #ifdef CONFIG_NAND_SPL
-       ldr     pc, _nand_boot
- _nand_boot: .word nand_boot
+       ldr     r0, _nand_boot_ofs
+       adr     r1, _start
+       add     pc, r0, r1
+ _nand_boot_ofs
+       : .word nand_boot - _start
  #else
  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
  #endif
+ _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
@@@ -375,8 -389,11 +389,11 @@@ stack_setup
        bic     sp, sp, #7              /* 8-byte alignment for ABI compliance */
  
  clear_bss:
-       ldr     r0, _bss_start          /* find start of bss segment        */
-       ldr     r1, _bss_end            /* stop here                        */
+       adr     r2, _start
+       ldr     r0, _bss_start_ofs      /* find start of bss segment        */
+       add     r0, r0, r2
+       ldr     r1, _bss_end_ofs        /* stop here                        */
+       add     r1, r1, r2
        mov     r2, #0x00000000         /* clear                            */
  
  #ifndef CONFIG_PRELOADER
@@@ -386,15 -403,19 +403,19 @@@ clbss_l:str     r2, [r0]                /* clear loop..
        bne     clbss_l
  #endif
  
-       ldr     pc, _start_armboot
+       ldr     r0, _start_armboot_ofs
+       adr     r1, _start
+       add     r0, r0, r1
+       ldr     pc, r0
  
+ _start_armboot_ofs:
  #ifdef CONFIG_NAND_SPL
_start_armboot: .word nand_boot
      .word nand_boot - _start
  #else
  #ifdef CONFIG_ONENAND_IPL
_start_armboot: .word start_oneboot
      .word start_oneboot - _start
  #else
_start_armboot: .word start_armboot
      .word start_armboot - _start
  #endif /* CONFIG_ONENAND_IPL */
  #endif /* CONFIG_NAND_SPL */
  
@@@ -487,7 -508,7 +508,7 @@@ cpu_init_crit
  #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
        ldr     r2, IRQ_STACK_START_IN          @ set base 2 words into abort stack
  #else
-       ldr     r2, _armboot_start
+       adr     r2, _start
        sub     r2, r2, #(CONFIG_SYS_MALLOC_LEN)
        sub     r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)   @ set base 2 words into abort stack
  #endif
  #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
        ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack (enter in banked mode)
  #else
-       ldr     r13, _armboot_start             @ setup our mode stack (enter in banked mode)
-       sub     r13, r13, #(CONFIG_SYS_MALLOC_LEN)      @ move past malloc pool
+       adr     r13, _start                     @ setup our mode stack (enter in banked mode)
+       sub     r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)     @ move past malloc pool
        sub     r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack
  #endif
  
index 8cbe3e74663c8c459b864d825c1f98be1de03456,e882487c25a86d62eba748807b953e786b309142..863de3ba0fc64cea888911ed1c49208749993aa2
@@@ -10,6 -10,7 +10,7 @@@
   *  Copyright (c) 2002        Gary Jennejohn <garyj@denx.de>
   *  Copyright (c) 2003        Richard Woodruff <r-woodruff2@ti.com>
   *  Copyright (c) 2003        Kshitij <kshitij@ti.com>
+  *  Copyright (c) 2010        Albert Aribaud <albert.aribaud@free.fr>
   *
   * See file CREDITS for list of people who contributed to this
   * project.
@@@ -116,24 -117,21 +117,21 @@@ _fiq
  
  .globl _TEXT_BASE
  _TEXT_BASE:
 -      .word   TEXT_BASE
 +      .word   CONFIG_SYS_TEXT_BASE
  
- #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
- .globl _armboot_start
- _armboot_start:
-       .word _start
- #endif
  /*
   * These are defined in the board-specific linker script.
+  * Subtracting _start from them lets the linker put their
+  * relative position in the executable instead of leaving
+  * them null.
   */
- .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) */
@@@ -153,30 -151,6 +151,6 @@@ FIQ_STACK_START
  IRQ_STACK_START_IN:
        .word   0x0badc0de
  
- .globl _datarel_start
- _datarel_start:
-       .word __datarel_start
- .globl _datarelrolocal_start
- _datarelrolocal_start:
-       .word __datarelrolocal_start
- .globl _datarellocal_start
- _datarellocal_start:
-       .word __datarellocal_start
- .globl _datarelro_start
- _datarelro_start:
-       .word __datarelro_start
- .globl _got_start
- _got_start:
-       .word __got_start
- .globl _got_end
- _got_end:
-       .word __got_end
  /*
   * the actual reset code
   */
@@@ -226,9 -200,8 +200,8 @@@ stack_setup
  
        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
        beq     clear_bss
  
@@@ -240,36 -213,54 +213,54 @@@ copy_loop
        blo     copy_loop
  
  #ifndef CONFIG_PRELOADER
-       /* fix got entries */
-       ldr     r1, _TEXT_BASE          /* 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
  #endif
  #endif        /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
  
  clear_bss:
  #ifndef CONFIG_PRELOADER
-       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                            */
  
@@@ -287,24 -278,33 +278,33 @@@ clbss_l:str     r2, [r0]                /* clear loop..
   * initialization, now running from RAM.
   */
  #ifdef CONFIG_NAND_SPL
-       ldr     pc, _nand_boot
+       ldr     r0, _nand_boot_ofs
+       mov     pc, r0
  
- _nand_boot: .word nand_boot
+ _nand_boot_ofs:
+       .word nand_boot
  #else
-       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
  #endif
  
+ _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
@@@ -333,10 -333,8 +333,8 @@@ relocate:                         /* relocate U-Boot to RA
        ldr     r1, _TEXT_BASE          /* test if we run from flash or RAM */
        cmp     r0, r1                  /* don't reloc during debug         */
        beq     stack_setup
-       ldr     r2, _armboot_start
-       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      /* r3 <- _bss_start - _start        */
+       add     r2, r0, r3              /* r2 <- source end address         */
  
  copy_loop:
        ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
@@@ -360,8 -358,11 +358,11 @@@ stack_setup
        bic     sp, sp, #7              /* 8-byte alignment for ABI compliance */
  
  clear_bss:
-       ldr     r0, _bss_start          /* find start of bss segment        */
-       ldr     r1, _bss_end            /* stop here                        */
+       adr     r2, _start
+       ldr     r0, _bss_start_ofs      /* find start of bss segment        */
+       add     r0, r0, r2
+       ldr     r1, _bss_end_ofs        /* stop here                        */
+       add     r1, r1, r2
        mov     r2, #0x00000000         /* clear                            */
  
  #ifndef CONFIG_PRELOADER
@@@ -374,13 -375,16 +375,16 @@@ clbss_l:str     r2, [r0]                /* clear loop..
        bl red_LED_on
  #endif /* CONFIG_PRELOADER */
  
-       ldr     pc, _start_armboot
+       ldr     r0, _start_armboot_ofs
+       adr     r1, _start
+       add     r0, r0, r1
+       ldr     pc, r0
  
- _start_armboot:
+ _start_armboot_ofs:
  #ifdef CONFIG_NAND_SPL
-       .word nand_boot
+       .word nand_boot - _start
  #else
-       .word start_armboot
+       .word start_armboot - _start
  #endif /* CONFIG_NAND_SPL */
  #endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
  
@@@ -469,7 -473,7 +473,7 @@@ cpu_init_crit
        sub     sp, sp, #S_FRAME_SIZE
        stmia   sp, {r0 - r12}  @ Save user registers (now in svc mode) r0-r12
  #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
-       ldr     r2, _armboot_start
+       adr     r2, _start
        sub     r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
        sub     r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)  @ set base 2 words into abort stack
  #else
  
        .macro get_bad_stack
  #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
-       ldr     r13, _armboot_start             @ setup our mode stack
+       adr     r13, _start             @ setup our mode stack
        sub     r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
        sub     r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
  #else
index 26f335a91613802f00073afe99db81a99753edf5,d5c053dc58576fd37bb55236e521c72e6246675d..64c86e97690c00b55076b5a588a4a19a00f2a3be
@@@ -67,7 -67,7 +67,7 @@@ _end_vect
  
  .globl _TEXT_BASE
  _TEXT_BASE:
 -      .word   TEXT_BASE
 +      .word   CONFIG_SYS_TEXT_BASE
  
  #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
  .globl _armboot_start
@@@ -78,13 -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 +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 +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 +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 +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
index d8e33fc5135d6f74fedb89ca574396d9ea95f2bc,8d3eb10789792c3fe1fbd37481c9227b6177185c..4124f0a9922e25d0d919e871107648bf859fd4fd
  #ifndef _ASM_CONFIG_H_
  #define _ASM_CONFIG_H_
  
- #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
  /* Relocation to SDRAM works on all ARM boards */
  #define CONFIG_RELOC_FIXUP_WORKS
- #endif
++
 +#define CONFIG_LMB
 +#define CONFIG_SYS_BOOT_RAMDISK_HIGH
  #endif
diff --combined arch/arm/lib/board.c
index 108e6c40c4cf84daa8a544a2c19bf65d8a522f9f,e411d9336b59e336efbe51f329a01baafcee3d90..ffe261bd4457e0eb9be0e74609c5efd5b09725ad
@@@ -147,7 -147,7 +147,7 @@@ static int display_banner (void
  #else
               _armboot_start,
  #endif
-              _bss_start, _bss_end);
+              _bss_start_ofs+_TEXT_BASE, _bss_end_ofs+_TEXT_BASE);
  #ifdef CONFIG_MODEM_SUPPORT
        debug ("Modem Support enabled\n");
  #endif
@@@ -409,6 -409,15 +409,6 @@@ void start_armboot (void
        enable_interrupts ();
  
        /* Perform network card initialisation if necessary */
 -#ifdef CONFIG_DRIVER_TI_EMAC
 -      /* XXX: this needs to be moved to board init */
 -extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
 -      if (getenv ("ethaddr")) {
 -              uchar enetaddr[6];
 -              eth_getenv_enetaddr("ethaddr", enetaddr);
 -              davinci_eth_set_mac_addr(enetaddr);
 -      }
 -#endif
  
  #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
        /* XXX: this needs to be moved to board init */
@@@ -508,7 -517,7 +508,7 @@@ void board_init_f (ulong bootflag
  
        memset ((void*)gd, 0, sizeof (gd_t));
  
-       gd->mon_len = _bss_end - _TEXT_BASE;
+       gd->mon_len = _bss_end_ofs;
  
        for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
                if ((*init_fnc_ptr)() != 0) {
@@@ -670,6 -679,7 +670,7 @@@ static char *failed = "*** failed ***\n
   *
   ************************************************************************
   */
  void board_init_r (gd_t *id, ulong dest_addr)
  {
        char *s;
  
        gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
  
-       monitor_flash_len = _bss_start - _TEXT_BASE;
+       monitor_flash_len = _bss_start_ofs;
        debug ("monitor flash len: %08lX\n", monitor_flash_len);
        board_init();   /* Setup chipselects */
  
        onenand_init();
  #endif
  
 +#ifdef CONFIG_GENERIC_MMC
 +       puts("MMC:   ");
 +       mmc_initialize(bd);
 +#endif
 +
  #ifdef CONFIG_HAS_DATAFLASH
        AT91F_DataflashInit();
        dataflash_print_info();
        enable_interrupts ();
  
        /* Perform network card initialisation if necessary */
 -#ifdef CONFIG_DRIVER_TI_EMAC
 -      /* XXX: this needs to be moved to board init */
 -extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
 -      if (getenv ("ethaddr")) {
 -              uchar enetaddr[6];
 -              eth_getenv_enetaddr("ethaddr", enetaddr);
 -              davinci_eth_set_mac_addr(enetaddr);
 -      }
 -#endif
 -
  #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
        /* XXX: this needs to be moved to board init */
        if (getenv ("ethaddr")) {
        board_late_init ();
  #endif
  
 -#ifdef CONFIG_GENERIC_MMC
 -      puts ("MMC:   ");
 -      mmc_initialize (gd->bd);
 -#endif
 -
  #ifdef CONFIG_BITBANGMII
        bb_miiphy_init();
  #endif
  
        /* NOTREACHED - no way out of command loop except booting */
  }
  #endif /* defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
  
  void hang (void)
index d07642f5cf70a57ea01e6d20266bb539586b696b,bf3581def241e35f0430ed24f422a2b73fe6efdc..2ffd1250af5b7244ff9ddbf21c9f83ad22968017
@@@ -23,5 -23,5 +23,6 @@@
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  # MA 02110-1301 USA
  #
- CONFIG_SYS_TEXT_BASE = 0x00100000
 +
 -TEXT_BASE = 0xfff90000
+ # TEXT_BASE must equal the intended FLASH location of u-boot.
++CONFIG_SYS_TEXT_BASE = 0xfff90000
index 4283c3e344ed09d8b9227b6cda9d248c1a91ce2b,8be6466b5a873eca85a70cd6affe031dbf45bda6..18b288392cf606a65008d693b545428fb9e32b06
@@@ -1,5 -1,5 +1,5 @@@
  ifdef CONFIG_NAND_SPL
 -TEXT_BASE = 0x810c0000
 +CONFIG_SYS_TEXT_BASE = 0x810c0000
  else
- CONFIG_SYS_TEXT_BASE = 0x81fc0000
 -TEXT_BASE = 0x81200000
++CONFIG_SYS_TEXT_BASE = 0x81200000
  endif
index 7f22154c618d9fd80fa985926849ebbffbf8d0a3,af1c82b6c282fe1d87e5160477fb59ce3adbb5a8..018d9207e0f04bfe1a2f3a89cf282767d4516698
@@@ -1,1 -1,4 +1,5 @@@
 -# with relocation TEXT_BASE can be anything, and making it 0
++# with relocation CONFIG_SYS_TEXT_BASE can be anything, and making it 0
+ # makes relative and absolute relocation fixups interchangeable.
 -#TEXT_BASE = 0
 -TEXT_BASE = 0xc0000000
++#CONFIG_SYS_TEXT_BASE = 0
++
 +CONFIG_SYS_TEXT_BASE = 0xc0000000
index 4ab3c7c0bd6be1feed94285534c750e02d48c542,b46347bb5b16679ca9f19ba12742defa611a94c9..8d328e09f9108c93c82f263f286f84322c4037ae
@@@ -1,50 -1,55 +1,55 @@@
  To make relocation on arm working, the following changes are done:
  
- Add new compilerflag:
+ At arch level: add linker flag -pie
  
- -fPIC
+       This causes the linker to generate fixup tables .rel.dyn and .dynsym,
+       which must be applied to the relocated image before transferring
+       control to it.
  
-       -> compiler generates position independent code
+       These fixups are described in the ARM ELF documentation as type 23
+       (program-base-relative) and 2 (symbol-relative)
  
- changes in board code:
+ At cpu level: modify linker file and add a relocation and fixup loop
  
- - dram_init:
-   - bd pointer is now at this point not accessible, so only
-     detect the real dramsize, and store it in gd->ram_size.
-     best detected with get_ram_size();
-     ToDo: move there also the dram initialization on boards where
-           it is possible.
-   - setup the bd_t dram bank info in the new function
-     dram_init_banksize().
+       the linker file must be modified to include the .rel.dyn and .dynsym
+       tables in the binary image, and to provide symbols for the relocation
+       code to access these tables
  
- - board.c code is adapted from ppc code
+       The relocation and fixup loop must be executed after executing
+       board_init_f at initial location and before executing board_init_r
+       at final location.
  
- - undef CONFIG_RELOC_FIXUP_WORKS
+ At board level:
  
-   -> cmdtabl, and subcommand table must be handled from "hand"
-      collected in section "__datarellocal_start".
+       dram_init(): bd pointer is now at this point not accessible, so only
+       detect the real dramsize, and store it in gd->ram_size. Bst detected
+       with get_ram_size().
  
-   - How To fixup the sections:
+ TODO: move also dram initialization there on boards where it is possible.
  
-     __datarel_start, __datarelrolocal_start, __datarellocal_start and
-     __datarelro_start
+       Setup of the the bd_t dram bank info is done in the new function
+       dram_init_banksize() called after bd is accessible.
  
-     automatically? Then it should be possible to define again
-     CONFIG_RELOC_FIXUP_WORKS
+ At lib level:
  
- - irq stack setup is now not longer on a fix position, instead it is
-   calculated in board_init_f, and stored in gd->irq_sp
+       Board.c code is adapted from ppc code
  
- -------------------------------------------------------------------------------------
+ At config level:
  
- To compile a board without relocation, define CONFIG_SYS_ARM_WITHOUT_RELOC
- This possibility will removed!! So please fix your board to compile without
- CONFIG_SYS_ARM_WITHOUT_RELOC defined!!!
+       Define CONFIG_RELOC_FIXUP_WORKS.
+       Undefine CONFIG_SYS_ARM_WITHOUT_RELOC
  
- -------------------------------------------------------------------------------------
+ * WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING *
+ Boards which are not fixed to support relocation will be REMOVED!
+ Eventually, CONFIG_SYS_ARM_WITHOUT_RELOC and CONFIG_RELOC_FIXUP_WORKS will
+ disappear and boards which have to migrated to relocation will disappear too.
  
- For boards which boot from nand_spl, it is possible to save a copy
+ -----------------------------------------------------------------------------
+ For boards which boot from nand_spl, it is possible to save one copy
 -if TEXT_BASE == relocation address! This prevents that uboot code
 +if CONFIG_SYS_TEXT_BASE == relocation address! This prevents that uboot code
  is copied again in relocate_code().
  
  example for the tx25 board:
@@@ -61,26 -66,26 +66,26 @@@ e) there it copy u-boot to CONFIG_SYS_N
  f) u-boot code steps through board_init_f() and calculates
     the relocation address and copy itself to it
  
 -If TEXT_BASE == relocation address, the copying of u-boot
 +If CONFIG_SYS_TEXT_BASE == relocation address, the copying of u-boot
  in f) could be saved.
  
- -------------------------------------------------------------------------------------
+ -----------------------------------------------------------------------------
  
- ToDo:
+ TODO
  
  - fill in bd_t infos (check)
  - adapt all boards
  
 -- maybe adapt TEXT_BASE (this must be checked from board maintainers)
 +- maybe adapt CONFIG_SYS_TEXT_BASE (this must be checked from board maintainers)
    This *must* be done for boards, which boot from NOR flash
  
 -  on other boards if TEXT_BASE = relocation baseaddr, this saves
 +  on other boards if CONFIG_SYS_TEXT_BASE = relocation baseaddr, this saves
    one copying from u-boot code.
  
  - new function dram_init_banksize() is actual board specific. Maybe
    we make a weak default function in arch/arm/lib/board.c ?
  
- -------------------------------------------------------------------------------------
+ -----------------------------------------------------------------------------
  
  Relocation with NAND_SPL (example for the tx25):
  
    and start with code execution on this address.
  
  - The First page contains u-boot code from u-boot:nand_spl/nand_boot_fsl_nfc.c
 -  which inits the dram, cpu registers, reloacte itself to TEXT_BASE  and loads
 +  which inits the dram, cpu registers, reloacte itself to CONFIG_SYS_TEXT_BASE  and loads
    the "real" u-boot to CONFIG_SYS_NAND_U_BOOT_DST and starts execution
    @CONFIG_SYS_NAND_U_BOOT_START
  
  - This u-boot does no ram int, nor cpu register setup. Just looks
    where it have to relocate and relocate itself to this address.
 -  If relocate address = TEXT_BASE(not the same, as the TEXT_BASE
 +  If relocate address = CONFIG_SYS_TEXT_BASE(not the same, as the TEXT_BASE
    from the nand_spl code), no need to copy, just go on with bss clear
    and jump to board_init_r.
  
- -------------------------------------------------------------------------------------
- Relocation:
- How to translate flash addresses in GOT to ram addresses.
- This is automagically done from code, but this example
- shows, how this magic code works ;-)
- (example on the qong board)
- Find a variable:
- a) search it in System.map
- (for example flash_info)
- a005b4c0 B BootpID
- a005b4c4 B BootpTry
- a005b4c8 b slave
- a005b4cc B flash_info
- ^^^^^^^^
- a005c908 b saved_sector.4002
- a005c910 b cfi_mtd_info
- a005c9c0 b cfi_mtd_names
- a005c9d0 B mtd_table
- ---------------------------------------
- b) create hexdump from u-boot code:
- hexdump -C u-boot > gnlmpfhex
- ---------------------------------------
- c) search the variables address in the hexdump
- *
- 0005fc80  00 00 00 00 00 00 00 00  2c 06 01 a0 18 cd 05 a0  |........,.......|
- 0005fc90  9c d4 05 a0 bc b4 05 a0  1c 7f 05 a0 f0 05 01 a0  |................|
- 0005fca0  08 5a 04 a0 1c ab 05 a0  ec a4 05 a0 98 c3 01 a0  |.Z..............|
- 0005fcb0  a0 d6 05 a0 04 71 05 a0  c0 f9 00 a0 3c cd 05 a0  |.....q......<...|
- 0005fcc0  cc b4 05 a0 f0 fa 00 a0  f0 d6 05 a0 10 86 05 a0  |................|
-           ^^^^^^^^^^^
- 0005fcd0  a4 16 06 a0 dc 64 05 a0  18 86 05 a0 52 48 05 a0  |.....d......RH..|
- 0005fce0  c0 86 05 a0 24 6e 02 a0  b4 6c 05 a0 b0 94 01 a0  |....$n...l......|
- 0005fcf0  1c 86 05 a0 50 85 05 a0  d4 0c 06 a0 bc 0b 06 a0  |....P...........|
- -> 0005fcc0
- ----------------------------------------
- d) know we calculate this address in RAM
-   8ff08000    (new address of code in RAM *1)
- + 0005fcc0
- - 00008000    (offset of text *2)
- ----------
-   8ff5fcc0    -> Addr GOT in RAM
- *1:
- activate debug and look for the line:
- Now running in RAM - U-Boot at: 8ff08000
-                                 ^^^^^^^^
-                                 new address of u-boot code in RAM
- *2:
- Section Headers:
-   [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
-   [ 0]                   NULL            00000000 000000 000000 00      0   0  0
-   [ 1] .text             PROGBITS        a0000000 008000 04599c 00  AX  0   0 32
-                                                   ^^^^^^
-                                                   Offset of text
- ----------------------------------------
- e) now we look in 8ff5fcc0 (RAM)
- QongEVB>md 0x8ff5fcc0
- 8ff5fcc0 : a005b4cc a000faf0 a005d6f0 a0058610  ................
-            ^^^^^^^^
-            Bingo, here we have the old flash address (when relocation
-            is working, here is the fixed ram address. see @ f, how
-            it gets calculated)
- ----------------------------------------
- f) now translate it in the new RAM address
-   a005b4cc
- - a0000000     TextBase
- + 8ff08000     new address of u-boot in ram
- ----------
-   8ff634cc
- QongEVB>mm 0x8ff5fcc0 0x8ff634cc 1
- QongEVB>md 0x8ff5fcc0
- 8ff5fcc0 : 8ff634cc a000faf0 a005d6f0 a0058610  .4..............
- 8ff5fcd0 : a00616a4 a00564dc a0058618 a0054852  .....d......RH..
- As this must be done for all address in the GOT, the u-boot
- code did this automagically ... :-)
- ----------------------------------------------
- g) check if the new address is really in the bss section:
- bss start:
- 8ff6054c      (8ff08000 + 0005854C monitorlen)
- bss end:
- 8ff698ac      (8ff08000 + 618AC)
- 8ff634cc is in bss :-)
- ----------------------------------------------
- h) u-boot prints:
- important  addresses:
- U-Boot code: A0000000 -> A005854C  BSS: -> A00618AC   TextBase 0xa0000000
- Now running in RAM - U-Boot at: 8ff08000              relocBase 0x8ff08000
- ---------
+ -----------------------------------------------------------------------------
  
- U-Boot 2010.06-rc2-00002-gf8fbb25-dirty (Jun 18 2010 - 17:07:19)
+ How ELF relocations 23 and 2 work.
  
- U-Boot code: A0000000 -> A005854C  BSS: -> A00618AC
- CPU:   Freescale i.MX31 at 398 MHz
- Board: DAVE/DENX Qong
- mon: FFFFFFFF gd->monLen: 000618AC
- Top of RAM usable for U-Boot at: 90000000
- LCD panel info: 640 x 480, 16 bit/pix
- Reserving 600k for LCD Framebuffer at: 8ff6a000
- Reserving 390k for U-Boot at: 8ff08000
- Reserving 1280k for malloc() at: 8fdc8000
- Reserving 28 Bytes for Board Info at: 8fdc7fe4
- Reserving 48 Bytes for Global Data at: 8fdc7fb4
- New Stack Pointer is: 8fdc7fb0
- RAM Configuration:
- Bank #0: 80000000 256 MiB
- mon: 0005854C gd->monLen: 000618AC
- Now running in RAM - U-Boot at: 8ff08000
+ TBC
  
  -------------------------------------------------------------------------------------