mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 07:31:15 +00:00
arm: implement ELF relocations
ELF relocation tables generated with linker option -pie can be used to fixup code and data in a single loop at relocation, removing the need for manual fixups anywhere else in the code. Signed-off-by: Albert Aribaud <albert.aribaud@free.fr>
This commit is contained in:
parent
89bca0ab69
commit
92d5ecba47
7 changed files with 156 additions and 290 deletions
|
@ -33,11 +33,6 @@ STANDALONE_LOAD_ADDR = 0xc100000
|
|||
endif
|
||||
endif
|
||||
|
||||
ifndef CONFIG_SYS_ARM_WITHOUT_RELOC
|
||||
# needed for relocation
|
||||
PLATFORM_RELFLAGS += -fPIC
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SYS_ARM_WITHOUT_RELOC
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_SYS_ARM_WITHOUT_RELOC
|
||||
endif
|
||||
|
@ -72,3 +67,8 @@ PLATFORM_LIBS += $(OBJTREE)/arch/arm/lib/eabi_compat.o
|
|||
endif
|
||||
endif
|
||||
LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds
|
||||
|
||||
ifndef CONFIG_SYS_ARM_WITHOUT_RELOC
|
||||
# needed for relocation
|
||||
PLATFORM_LDFLAGS += -pie
|
||||
endif
|
||||
|
|
|
@ -10,6 +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.
|
||||
|
@ -118,22 +119,19 @@ _fiq:
|
|||
_TEXT_BASE:
|
||||
.word 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 @@ 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 @@ 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 @@ 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 @@ 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
|
||||
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 @@ relocate: /* relocate U-Boot to RAM */
|
|||
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 @@ 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 @@ 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 @@ 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
|
||||
|
@ -507,7 +511,7 @@ cpu_init_crit:
|
|||
|
||||
.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
|
||||
|
|
|
@ -41,21 +41,19 @@ SECTIONS
|
|||
. = ALIGN(4);
|
||||
.data : {
|
||||
*(.data)
|
||||
__datarel_start = .;
|
||||
*(.data.rel)
|
||||
__datarelrolocal_start = .;
|
||||
*(.data.rel.ro.local)
|
||||
__datarellocal_start = .;
|
||||
*(.data.rel.local)
|
||||
__datarelro_start = .;
|
||||
*(.data.rel.ro)
|
||||
}
|
||||
|
||||
__got_start = .;
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
__got_end = .;
|
||||
__rel_dyn_start = .;
|
||||
.rel.dyn : { *(.rel.dyn) }
|
||||
__rel_dyn_end = .;
|
||||
|
||||
__dynsym_start = .;
|
||||
.dynsym : { *(.dynsym) }
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
. = .;
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
|
@ -65,4 +63,10 @@ SECTIONS
|
|||
__bss_start = .;
|
||||
.bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
|
||||
_end = .;
|
||||
|
||||
/DISCARD/ : { *(.dynstr*) }
|
||||
/DISCARD/ : { *(.dynamic*) }
|
||||
/DISCARD/ : { *(.plt*) }
|
||||
/DISCARD/ : { *(.interp*) }
|
||||
/DISCARD/ : { *(.gnu*) }
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
#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
|
||||
#endif
|
||||
|
|
|
@ -30,18 +30,18 @@
|
|||
#define _U_BOOT_ARM_H_ 1
|
||||
|
||||
/* for the following variables, see start.S */
|
||||
extern ulong _bss_start; /* code + data end == BSS start */
|
||||
extern ulong _bss_end; /* BSS end */
|
||||
extern ulong _bss_start_ofs; /* BSS start relative to _start */
|
||||
extern ulong _bss_end_ofs; /* BSS end relative to _start */
|
||||
extern ulong IRQ_STACK_START; /* top of IRQ stack */
|
||||
extern ulong FIQ_STACK_START; /* top of FIQ stack */
|
||||
#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
|
||||
extern ulong _armboot_start; /* code start */
|
||||
extern ulong _armboot_start_ofs; /* code start */
|
||||
#else
|
||||
extern ulong _TEXT_BASE; /* code start */
|
||||
extern ulong _datarel_start;
|
||||
extern ulong _datarelrolocal_start;
|
||||
extern ulong _datarellocal_start;
|
||||
extern ulong _datarelro_start;
|
||||
extern ulong _datarel_start_ofs;
|
||||
extern ulong _datarelrolocal_start_ofs;
|
||||
extern ulong _datarellocal_start_ofs;
|
||||
extern ulong _datarelro_start_ofs;
|
||||
extern ulong IRQ_STACK_START_IN; /* 8 bytes in IRQ stack */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -517,7 +517,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) {
|
||||
|
@ -679,6 +679,7 @@ static char *failed = "*** failed ***\n";
|
|||
*
|
||||
************************************************************************
|
||||
*/
|
||||
|
||||
void board_init_r (gd_t *id, ulong dest_addr)
|
||||
{
|
||||
char *s;
|
||||
|
@ -702,7 +703,7 @@ void board_init_r (gd_t *id, ulong dest_addr)
|
|||
|
||||
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 */
|
||||
|
||||
|
@ -914,6 +915,7 @@ extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
|
|||
|
||||
/* NOTREACHED - no way out of command loop except booting */
|
||||
}
|
||||
|
||||
#endif /* defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
|
||||
|
||||
void hang (void)
|
||||
|
|
|
@ -1,49 +1,54 @@
|
|||
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 *
|
||||
|
||||
For boards which boot from nand_spl, it is possible to save a copy
|
||||
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 one copy
|
||||
if TEXT_BASE == relocation address! This prevents that uboot code
|
||||
is copied again in relocate_code().
|
||||
|
||||
|
@ -64,9 +69,9 @@ f) u-boot code steps through board_init_f() and calculates
|
|||
If 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
|
||||
|
@ -80,7 +85,7 @@ ToDo:
|
|||
- 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):
|
||||
|
||||
|
@ -98,158 +103,11 @@ Relocation with NAND_SPL (example for the tx25):
|
|||
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)
|
||||
How ELF relocations 23 and 2 work.
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
|
||||
|
|
Loading…
Reference in a new issue