
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@gmail.com Cc: Albert Aribaud albert.u.boot@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