diff options
author | cognet <cognet@FreeBSD.org> | 2010-11-01 21:04:23 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2010-11-01 21:04:23 +0000 |
commit | 71407681fdd1b75689f0d0a1e99666c0b45dfc6a (patch) | |
tree | 7e278202cc6548bf07fe1689d58e09152d1e5880 /sys/arm | |
parent | a4ab528826d1ac9cc9de0ba3fead29d68b978e3e (diff) | |
download | FreeBSD-src-71407681fdd1b75689f0d0a1e99666c0b45dfc6a.zip FreeBSD-src-71407681fdd1b75689f0d0a1e99666c0b45dfc6a.tar.gz |
Try to be a little smart at guessing where _start is located in flash, instead
of relying on a binutils bug.
Reported by: dim
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/arm/elf_trampoline.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c index 0f725c8..4adb025 100644 --- a/sys/arm/arm/elf_trampoline.c +++ b/sys/arm/arm/elf_trampoline.c @@ -159,7 +159,7 @@ _startC(void) #if defined(FLASHADDR) && defined(LOADERRAMADDR) unsigned int pc; - __asm __volatile("adr %0, _start\n" + __asm __volatile("mov %0, pc\n" : "=r" (pc)); if ((FLASHADDR > LOADERRAMADDR && pc >= FLASHADDR) || (FLASHADDR < LOADERRAMADDR && pc < LOADERRAMADDR)) { @@ -173,11 +173,13 @@ _startC(void) */ unsigned int target_addr; unsigned int tmp_sp; + uint32_t src_addr = (uint32_t)&_start - PHYSADDR + FLASHADDR + + (pc - FLASHADDR - ((uint32_t)&_startC - PHYSADDR)) & 0xfffff000; target_addr = (unsigned int)&_start - PHYSADDR + LOADERRAMADDR; tmp_sp = target_addr + 0x100000 + (unsigned int)&_end - (unsigned int)&_start; - memcpy((char *)target_addr, (char *)pc, + memcpy((char *)target_addr, (char *)src_addr, (unsigned int)&_end - (unsigned int)&_start); /* Temporary set the sp and jump to the new location. */ __asm __volatile( |