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 <dant...@gmail.com> Cc: Albert Aribaud <albert.u.b...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot