diff options
| author | Graeme Russ <graeme.russ@gmail.com> | 2010-10-07 20:03:33 +1100 | 
|---|---|---|
| committer | Graeme Russ <graeme.russ@gmail.com> | 2010-10-07 20:03:33 +1100 | 
| commit | c868af3e57610b41c6ed4fd8d8744d8cc0a21b29 (patch) | |
| tree | 6d2d1efd72aa3e7fc506f7ac65f106d163410ea5 /arch/i386/lib/board.c | |
| parent | f2ff75c0a25eb78b4b86fd96c5f0be9dd327e2d7 (diff) | |
| download | olio-uboot-2014.01-c868af3e57610b41c6ed4fd8d8744d8cc0a21b29.tar.xz olio-uboot-2014.01-c868af3e57610b41c6ed4fd8d8744d8cc0a21b29.zip | |
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/board.c')
| -rw-r--r-- | arch/i386/lib/board.c | 23 | 
1 files changed, 13 insertions, 10 deletions
| diff --git a/arch/i386/lib/board.c b/arch/i386/lib/board.c index 9c2f77fd5..1129918fe 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(); +	/* 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(); +		/* 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) |