diff options
author | Graeme Russ <graeme.russ@gmail.com> | 2010-10-07 09:03:33 (GMT) |
---|---|---|
committer | Graeme Russ <graeme.russ@gmail.com> | 2010-10-07 09:03:33 (GMT) |
commit | c868af3e57610b41c6ed4fd8d8744d8cc0a21b29 (patch) | |
tree | 6d2d1efd72aa3e7fc506f7ac65f106d163410ea5 /arch/i386/lib | |
parent | f2ff75c0a25eb78b4b86fd96c5f0be9dd327e2d7 (diff) | |
download | u-boot-fsl-qoriq-c868af3e57610b41c6ed4fd8d8744d8cc0a21b29.tar.xz |
x86: Implement fully relocatable image
u-boot.bin can be loaded at any 4-byte aligned memory location and directly
'jumped' to using the 'go' command using the load address as the start
address. Doing so performs a 'warm boot' which skips memory initialisation
and other low-level initialisations, relocates U-Boot to upper memory and
starts U-Boot in RAM as per normal 'cold boot'
Diffstat (limited to 'arch/i386/lib')
-rw-r--r-- | arch/i386/lib/board.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/arch/i386/lib/board.c b/arch/i386/lib/board.c index 9c2f77f..1129918 100644 --- a/arch/i386/lib/board.c +++ b/arch/i386/lib/board.c @@ -190,18 +190,21 @@ void board_init_f (ulong gdp) dest_addr = (void *)gdp - (bss_end - text_start); rel_offset = text_start - dest_addr; - /* First stage CPU initialization */ - if (cpu_init_f() != 0) - hang(); - - /* First stage Board initialization */ - if (board_early_init_f() != 0) - hang(); + /* Perform low-level initialization only when cold booted */ + if (((gd_t *)gdp)->flags & GD_FLG_COLD_BOOT) { + /* First stage CPU initialization */ + if (cpu_init_f() != 0) + hang(); + + /* First stage Board initialization */ + if (board_early_init_f() != 0) + hang(); + } /* Copy U-Boot into RAM */ dst_addr = (ulong *)dest_addr; - src_addr = (ulong *)text_start; - end_addr = (ulong *)data_end; + src_addr = (ulong *)(text_start + ((gd_t *)gdp)->load_off); + end_addr = (ulong *)(data_end + ((gd_t *)gdp)->load_off); while (src_addr < end_addr) *dst_addr++ = *src_addr++; @@ -214,8 +217,8 @@ void board_init_f (ulong gdp) *dst_addr++ = 0x00000000; /* Perform relocation adjustments */ - re_src = (Elf32_Rel *)rel_dyn_start; - re_end = (Elf32_Rel *)rel_dyn_end; + re_src = (Elf32_Rel *)(rel_dyn_start + ((gd_t *)gdp)->load_off); + re_end = (Elf32_Rel *)(rel_dyn_end + ((gd_t *)gdp)->load_off); do { if (re_src->r_offset >= TEXT_BASE) |