[U-Boot] [PATCH] arm: add IPL support

Kuo-Jung Su dantesu at gmail.com
Wed Dec 4 04:50:48 CET 2013


Initial Program Loader (IPL) usually runs with .text and .rodata
in ROM, while .data and .bss reside in RAM.

This patch uses the AT keyword to specify load address,
and a small code snippet in crt0.S to restore .data section
at runtime.

Example usage:
Assume the target device has a 4KB ROM at 0x00000000 and a
4KB SRAM at 0xA0000000, the IPL/SPL config could be:

#define CONFIG_SPL_MAX_SIZE  0x1000 /* text + data, no bss */
#define CONFIG_SPL_TEXT_BASE 0x00000000
#define CONFIG_SPL_DATA_BASE 0xA0000000
#define CONFIG_SPL_STACK     0xA0001000

Signed-off-by: Kuo-Jung Su <dantesu at gmail.com>
Cc: Albert Aribaud <albert.u.boot at aribaud.net>
---
 README                      |   10 ++++++++++
 arch/arm/cpu/u-boot-spl.lds |   26 ++++++++++++++++++++++++--
 arch/arm/lib/crt0.S         |   22 ++++++++++++++++++++++
 spl/Makefile                |    6 ++++++
 4 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/README b/README
index a8d3039..992064a 100644
--- a/README
+++ b/README
@@ -3094,6 +3094,16 @@ FIT uImage format:
 		Address to relocate to.  If unspecified, this is equal to
 		CONFIG_SPL_TEXT_BASE (i.e. no relocation is done).

+		CONFIG_SPL_DATA_BASE
+		Link address for the .data and .bss within the SPL binary.
+		CONFIG_SPL_MAX_FOOTPRINT and CONFIG_SPL_DATA_BASE
+		must not be both defined at the same time.
+
+		CONFIG_SPL_DATA_MAX_SIZE
+		Maximum size in memory allocated to the SPL .data + .bss.
+		When defined, the linker checks that the actual memory used
+		by SPL from __data_start to __bss_end does not exceed it.
+
 		CONFIG_SPL_BSS_START_ADDR
 		Link address for the BSS within the SPL binary.

diff --git a/arch/arm/cpu/u-boot-spl.lds b/arch/arm/cpu/u-boot-spl.lds
index 36cc54a..ea6284f 100644
--- a/arch/arm/cpu/u-boot-spl.lds
+++ b/arch/arm/cpu/u-boot-spl.lds
@@ -26,15 +26,28 @@ SECTIONS
 	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }

 	. = ALIGN(4);
-	.data : {
+
+#if defined(CONFIG_SPL_DATA_BASE)
+	__image_copy_end = .;
+
+	.data : AT ( __image_copy_end )
+#else
+	.data :
+#endif
+	{
+		__data_start = .;
 		*(.data*)
+		. = ALIGN(4);
+		__data_end = .;
 	}

 	. = ALIGN(4);

 	. = .;

+#if !defined(CONFIG_SPL_DATA_BASE)
 	__image_copy_end = .;
+#endif

 	.rel.dyn : {
 		__rel_dyn_start = .;
@@ -59,11 +72,20 @@ SECTIONS
 	/DISCARD/ : { *(.gnu*) }
 }

-#if defined(CONFIG_SPL_MAX_SIZE)
+#if defined(CONFIG_SPL_MAX_SIZE) && defined(CONFIG_SPL_DATA_BASE)
+ASSERT((__image_copy_end - __image_copy_start) + \
+	(__data_end - __data_start) < (CONFIG_SPL_MAX_SIZE), \
+	"SPL image too big");
+#elif defined(CONFIG_SPL_MAX_SIZE)
 ASSERT(__image_copy_end - __image_copy_start < (CONFIG_SPL_MAX_SIZE), \
 	"SPL image too big");
 #endif

+#if defined(CONFIG_SPL_DATA_MAX_SIZE)
+ASSERT(__bss_end - __data_start < (CONFIG_SPL_DATA_MAX_SIZE), \
+	"SPL image DATA plus BSS too big");
+#endif
+
 #if defined(CONFIG_SPL_BSS_MAX_SIZE)
 ASSERT(__bss_end - __bss_start < (CONFIG_SPL_BSS_MAX_SIZE), \
 	"SPL image BSS too big");
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
index ac54b93..46d0e03 100644
--- a/arch/arm/lib/crt0.S
+++ b/arch/arm/lib/crt0.S
@@ -58,6 +58,28 @@
 ENTRY(_main)

 /*
+ * Restore .data (initialized) section
+ */
+
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_DATA_BASE)
+
+	/* Load values from the board-specific linker script. */
+	ldr r0, =__image_copy_end /* source start address */
+	ldr r1, =__data_start
+	ldr r2, =__data_end
+	sub r2, r2, r1
+	add r2, r0, r2            /* source end address   */
+	ldr r1, =CONFIG_SPL_DATA_BASE
+
+data_copy:
+	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] */
+	blo   data_copy
+
+#endif	/* CONFIG_SPL_BUILD && CONFIG_SPL_DATA_BASE */
+
+/*
  * Set up initial C runtime environment and call board_init_f(0).
  */

diff --git a/spl/Makefile b/spl/Makefile
index 29d7818..540ef8c 100644
--- a/spl/Makefile
+++ b/spl/Makefile
@@ -54,6 +54,12 @@ ifeq ($(CPU),mpc85xx)
 START += $(START_PATH)/resetvec.o
 endif

+ifdef CONFIG_SPL_DATA_BASE
+LDFLAGS += -Ttext $(CONFIG_SPL_TEXT_BASE) -Tdata $(CONFIG_SPL_DATA_BASE)
+else
+LDFLAGS += -Ttext $(CONFIG_SPL_TEXT_BASE)
+endif
+
 LIBS-y += arch/$(ARCH)/lib/

 LIBS-y += $(CPUDIR)/
--
1.7.9.5



More information about the U-Boot mailing list