---
 arch/arm/cpu/arm926ejs/start.S |    8 ++++-
 arch/arm/lib/board.c           |   57 +++++++++++++++++++++++++++++++++++++++-
 include/configs/top9000_9xe.h  |    1 +
 3 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S
index 5a7ae7e..b7517db 100644
--- a/arch/arm/cpu/arm926ejs/start.S
+++ b/arch/arm/cpu/arm926ejs/start.S
@@ -213,7 +213,7 @@ relocate_code:
        /* Set up the stack                                                 */
 stack_setup:
        mov     sp, r4
-
+#ifndef CONFIG_USE_C_RELOCATION
        adr     r0, _start
        ldr     r2, _TEXT_BASE
        ldr     r3, _bss_start_ofs
@@ -266,7 +266,7 @@ fixnext:
        str     r1, [r0]
        add     r2, r2, #8      /* each rel.dyn entry is 8 bytes */
        cmp     r2, r3
-       ble     fixloop
+       blt     fixloop
 #endif
 #endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
 
@@ -288,6 +288,7 @@ clbss_l:str r2, [r0]                /* clear loop...        
            */
        bl coloured_LED_init
        bl red_LED_on
 #endif
+#endif /* CONFIG_USE_C_RELOCATION */
 
 /*
  * We are done. Do not return, instead branch to second part of board
@@ -314,10 +315,13 @@ _board_init_r_ofs:
        .word board_init_r - _start
 #endif
 
+.globl _rel_dyn_start_ofs
 _rel_dyn_start_ofs:
        .word __rel_dyn_start - _start
+.globl _rel_dyn_end_ofs
 _rel_dyn_end_ofs:
        .word __rel_dyn_end - _start
+.globl _dynsym_start_ofs
 _dynsym_start_ofs:
        .word __dynsym_start - _start
 
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index e411d93..0b6b3ed 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -37,7 +37,7 @@
  * IRQ Stack: 00ebff7c
  * FIQ Stack: 00ebef7c
  */
-
+#define DEBUG
 #include <common.h>
 #include <command.h>
 #include <malloc.h>
@@ -50,6 +50,10 @@
 #include <onenand_uboot.h>
 #include <mmc.h>
 
+#ifdef CONFIG_USE_C_RELOCATION
+#include <elf.h>
+#endif
+
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif
@@ -509,6 +513,15 @@ void board_init_f (ulong bootflag)
        init_fnc_t **init_fnc_ptr;
        gd_t *id;
        ulong addr, addr_sp;
+#ifdef CONFIG_USE_C_RELOCATION
+       extern ulong _dynsym_start_ofs;
+       extern ulong _rel_dyn_start_ofs;
+       extern ulong _rel_dyn_end_ofs;
+       extern ulong _bss_start_ofs;
+       extern ulong _bss_end_ofs;
+       Elf32_Rel *rel_dyn_ptr;
+       ulong *p;
+#endif
 
        /* Pointer is writable since we allocated a register for it */
        gd = (gd_t *) (CONFIG_SYS_INIT_SP_ADDR);
@@ -661,6 +674,48 @@ void board_init_f (ulong bootflag)
        debug ("relocation Offset is: %08lx\n", gd->reloc_off);
        memcpy (id, (void *)gd, sizeof (gd_t));
 
+#ifdef CONFIG_USE_C_RELOCATION
+       /* TODO: check for identical source and destination */
+       /* TODO: check for overlapping */
+       /* copy image, including initialized data */
+       debug ("memcpy(%08lx,%08lx,%ld)\n",
+               addr, _TEXT_BASE, _bss_start_ofs);
+       memcpy ((void *)addr, (void *)_TEXT_BASE, _bss_start_ofs);
+       /* now fix the code */
+       debug ("_dynsym_start_ofs=%08lx _rel_dyn_start_ofs=%08lx 
_rel_dyn_end_ofs=%08lx\n",
+               _dynsym_start_ofs, _rel_dyn_start_ofs, _rel_dyn_end_ofs);
+       for (rel_dyn_ptr = (Elf32_Rel *)(_TEXT_BASE + _rel_dyn_start_ofs);
+                       rel_dyn_ptr < (Elf32_Rel *)(_TEXT_BASE + 
_rel_dyn_end_ofs);
+                       rel_dyn_ptr++) {
+               ulong *patchaddr = (ulong *) (rel_dyn_ptr->r_offset + 
gd->reloc_off);
+               debug ("patch %08lx : %08lx\n",
+                       (ulong)patchaddr, (ulong)rel_dyn_ptr->r_info);
+               switch (ELF32_R_TYPE(rel_dyn_ptr->r_info)) {
+               case 23: /* rel fixup */
+                       *patchaddr += gd->reloc_off;
+                       break;
+               case 2: /* abs fixup */
+                       {
+                               Elf32_Sym *sym = (Elf32_Sym *)(_TEXT_BASE + 
_dynsym_start_ofs);
+                               sym += ELF32_R_SYM(rel_dyn_ptr->r_info);
+                               *patchaddr = gd->reloc_off + sym->st_value;
+                       }
+                       break;
+               default: /* unhandled fixup */
+                       break;
+               }
+       }
+       /* clear BSS */
+# ifndef CONFIG_PRELOADER
+       debug ("clearing BSS %08lx..%08lx\n",
+               addr + _bss_start_ofs, addr + _bss_end_ofs);
+       for (p = (ulong *)(addr + _bss_start_ofs);
+                       p < (ulong *)(addr + _bss_end_ofs);
+                       *p++ = 0)
+               ;
+# endif
+#endif
+       debug ("calling relocate_code\n");
        relocate_code (addr_sp, id, addr);
 
        /* NOTREACHED - relocate_code() does not return */
diff --git a/include/configs/top9000_9xe.h b/include/configs/top9000_9xe.h
index f7fa198..e4ca026 100644
--- a/include/configs/top9000_9xe.h
+++ b/include/configs/top9000_9xe.h
@@ -73,6 +73,7 @@
 #define        CONFIG_SKIP_LOWLEVEL_INIT
 /*#define CONFIG_SKIP_RELOCATE_UBOOT*/
 /*#define CONFIG_SYS_ARM_WITHOUT_RELOC*/
+#define CONFIG_USE_C_RELOCATION
 #define CONFIG_RELOC_FIXUP_WORKS
 #define        CONFIG_SYS_NO_ICACHE
 #define        CONFIG_SYS_NO_DCACHE
-- 
1.5.6.5

_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to