[U-Boot] [PATCH] futile c relocation attempt
Reinhard Meyer
u-boot at emk-elektronik.de
Tue Oct 5 16:48:52 CEST 2010
---
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
More information about the U-Boot
mailing list