[U-Boot] [PATCH] [NEXT] arm926ejs: add split relocation support

Albert Aribaud albert.aribaud at free.fr
Tue Sep 14 20:25:41 CEST 2010


Many arm926ejs-based SoCs boot at 0xffff0000.
Currently these last 64 KB of flash are wasted just
for a jump to the location where u-boot was flashed.
This commit provides split relocation where the first
part of u-boot is stored from the reset address to the
end of the flash, and the second part is stored below
the first one.
This allows booting directly into _start at 0xffff0000,
thus fully using the last flash sector. For the ED Mini
V2, this frees 12.5% of the flash for other uses.

Signed-off-by: Albert Aribaud <albert.aribaud at free.fr>
---
As indicated in the subject line, this patch is *not* a bugfix
and thus *not* expected to be integrated into 2010.09.

It was heavily tested on an ED Mini V2 and a 5Big Network. All
the following cases were debugged step by step through JTAG:

- boot from RAM (with relocation, without low level init)
- boot from linear image in FLASH (with reloc & ll init)
- boot from split image in FLASH (with reloc & ll init)

'checkpatch.pl --no-tree' reported 0 errors and warnings.

 arch/arm/cpu/arm926ejs/start.S |   81 +++++++++++++++++++++++++++++++++------
 1 files changed, 68 insertions(+), 13 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S
index cf40ce1..9a0a9ef 100644
--- a/arch/arm/cpu/arm926ejs/start.S
+++ b/arch/arm/cpu/arm926ejs/start.S
@@ -5,8 +5,8 @@
  *
  *  ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
  *
- *  Copyright (c) 2001	Marius Gröger <mag at sysgo.de>
- *  Copyright (c) 2002	Alex Züpke <azu at sysgo.de>
+ *  Copyright (c) 2001	Marius Gröger <mag at sysgo.de>
+ *  Copyright (c) 2002	Alex Züpke <azu at sysgo.de>
  *  Copyright (c) 2002	Gary Jennejohn <garyj at denx.de>
  *  Copyright (c) 2003	Richard Woodruff <r-woodruff2 at ti.com>
  *  Copyright (c) 2003	Kshitij <kshitij at ti.com>
@@ -166,21 +166,74 @@ reset:
 	bl	cpu_init_crit
 #endif
 
+/*
+ * This code copies SIZE bytes of u-boot from 'source' _start (in FLASH)
+ * to 'destination' _TEXT_BASE (in RAM) RAM. It can handle two cases:
+ *
+ * 1) source is entirely located at [_start,_start+_bss_start-_armboot_start[
+ *    i.e. u-boot.bin was linearly written to FLASH (this is the case when
+ *    the target's reset vector can be _start, or points to some code which
+ *    will eventually jump inside FLASH to _start)
+ *
+ * 2) source was split in two parts, one located at [_start,0x1.0000.0000[
+ *    (for SIZE1 bytes where SIZE1 = (0x1.0000.000 - _start) and one located
+ *    at [_start-A, SIZE-SIZE1[ where A = (_bss_start-_armboot_start) rounded
+ *    up to the nearest multiple of SIZE1. This is the case when the target's
+ *    reset vector must point directly to _start but there is not enough room
+ *    between _start and the end of the 32-bit addressable FLASH.
+ *
+ * Example for the Orion5x 88F5182, which resets at 0xFFFF0000, and with an
+ * overall u-boot size of 0x0001CAFE:
+ * - the first 64 KB of u-boot.bin are flashed at [0xFFFF0000, 0x100000000[;
+ * - there are 0xCAFE bytes left, which take up one 64KB block. The second
+ *   part of u-boot will thus be flashed at [0xfffE0000, 0xfffECAFE[.
+ *
+ * To determine if the copy must be split, we taken the start addresse
+ * of the source and add the source length to it to form the end address.
+ * if this end address is below the start address, then the image was split.
+ * If it is above the start address, the image was not split.
+ */
+
 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
-relocate:				/* relocate U-Boot to RAM	    */
+	/* relocate U-Boot to RAM */
+relocate:
+	/* skip copy if source == destination */
 	adr	r0, _start		/* r0 <- current position of code   */
 	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
 	cmp     r0, r1                  /* don't reloc during debug         */
 	beq     stack_setup
+
+	/* skip split copying if copy is split */
 	ldr	r2, _armboot_start
 	ldr	r3, _bss_start
-	sub	r2, r3, r2		/* r2 <- size of armboot            */
-	add	r2, r0, r2		/* r2 <- source end address         */
+	sub	r4, r3, r2		/* r4 <- size of armboot            */
+	add	r2, r0, r4		/* r2 <- source end address         */
+	cmp	r2, r0			/* does the source rollover?        */
+	bhi	copy_loop		/* no: copy is linear, go do it.    */
+
+	/* block size is 0x1.0000.0000 - _start */
+	rsb	r3, r0, #0
+
+	/* round u-boot size up to the nearest multiple of block size */
+	sub	r3, r3, #1
+	orr	r4, r4, r3
+	add	r4, r4, #1
+
+	/* copy second part, end condition is r0 rollover to 0 */
+copy_second:
+	ldmia	r0!, {r5-r12}		/* copy from source address [r0]    */
+	stmia	r1!, {r5-r12}		/* copy to   target address [r1]    */
+	cmp	r0, #0			/* until source end address [#0]    */
+	bne	copy_second
+
+	/* move source start and end back by the u-boot size rounded up */
+	sub	r0, r0, r4		/* r0 <- source address of 2nd part */
+	sub	r2, r2, r4		/* r2 <- source end adr of 2nd part */
 
 copy_loop:
-	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
-	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
-	cmp	r0, r2			/* until source end addreee [r2]    */
+	ldmia	r0!, {r5-r12}		/* copy from source address [r0]    */
+	stmia	r1!, {r5-r12}		/* copy to   target address [r1]    */
+	cmp	r0, r2			/* until source end address [r2]    */
 	ble	copy_loop
 #endif	/* CONFIG_SKIP_RELOCATE_UBOOT */
 
@@ -189,14 +242,14 @@ stack_setup:
 	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
 	sub	sp, r0, #128		/* leave 32 words for abort-stack   */
 #ifndef CONFIG_PRELOADER
-	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN	/* malloc area                      */
-	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                        */
+	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN	/* malloc area              */
+	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */
 #ifdef CONFIG_USE_IRQ
 	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
 #endif
 #endif /* CONFIG_PRELOADER */
 	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
-	bic	sp, sp, #7		/* 8-byte alignment for ABI compliance */
+	bic	sp, sp, #7		/* ABI-compliant 8-bit alignment    */
 
 clear_bss:
 	ldr	r0, _bss_start		/* find start of bss segment        */
@@ -310,7 +363,8 @@ cpu_init_crit:
 
 	ldr	r2, _armboot_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
+	@ reserve a couple spots in abort stack
+	sub	r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)
 	@ get values for "aborted" pc and cpsr (into parm regs)
 	ldmia	r2, {r2 - r3}
 	add	r0, sp, #S_FRAME_SIZE		@ grab pointer to old stack
@@ -344,7 +398,8 @@ cpu_init_crit:
 	.macro get_bad_stack
 	ldr	r13, _armboot_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
+	@ reserve a couple spots in abort stack
+	sub	r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8)
 
 	str	lr, [r13]	@ save caller lr in position 0 of saved stack
 	mrs	lr, spsr	@ get the spsr
-- 
1.7.0.4



More information about the U-Boot mailing list