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

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

On Wed, Dec 04, 2013 at 11:50:48AM +0800, Kuo-Jung Su wrote:
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
Can you provide an example user of this functionality? Thanks.

2013/12/6 Tom Rini trini@ti.com:
On Wed, Dec 04, 2013 at 11:50:48AM +0800, Kuo-Jung Su wrote:
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
Can you provide an example user of this functionality? Thanks.
-- Tom
If you're looking for a real device, unfortunately there is no such device right now, it's a shiny new design which just came out last week.
If you're looking for a way for verification:
1. A real device with a NOR flash for ROM emulation. (e.g., Faraday A369 EVB)
2. A virtual device emulator. (e.g., Qemu)
This is the best option for you, the Qemu model for Faraday A369 is available at my github account. Please use the command bellow to grab the source tree if necessary.
$ git clone -b qemu-1.5.1 https://github.com/dantesu1218/qemu.git $ cd qemu $ ./configure --target-list=arm-softmmu $ make
The example IPL code for the up-coming Faraday A369 U-boot is also available:
$ git clone -b u-boot-2014.01 https://github.com/dantesu1218/u-boot.git $ cd u-boot $ make a369evb_ipl_config $ make
You could also directly grab the pre-built binaries for quick verification.
$ wget https://drive.google.com/file/d/0BwfiewvSmUgAMlBnUkZQb3FMVkE/edit?usp=sharin... $ tar xf u-boot-a369-ipl.tar.bz2 $ cd u-boot-a369-ipl $ make

On Mon, Dec 09, 2013 at 04:07:29PM +0800, Kuo-Jung Su wrote:
2013/12/6 Tom Rini trini@ti.com:
On Wed, Dec 04, 2013 at 11:50:48AM +0800, Kuo-Jung Su wrote:
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
Can you provide an example user of this functionality? Thanks.
-- Tom
If you're looking for a real device, unfortunately there is no such device right now, it's a shiny new design which just came out last week.
If you're looking for a way for verification:
A real device with a NOR flash for ROM emulation. (e.g., Faraday A369 EVB)
A virtual device emulator. (e.g., Qemu)
This is the best option for you, the Qemu model for Faraday A369 is
available at my github account. Please use the command bellow to grab the source tree if necessary.
$ git clone -b qemu-1.5.1 https://github.com/dantesu1218/qemu.git $ cd qemu $ ./configure --target-list=arm-softmmu $ make
The example IPL code for the up-coming Faraday A369 U-boot is also available:
$ git clone -b u-boot-2014.01 https://github.com/dantesu1218/u-boot.git $ cd u-boot $ make a369evb_ipl_config $ make
You could also directly grab the pre-built binaries for quick verification.
$ wget https://drive.google.com/file/d/0BwfiewvSmUgAMlBnUkZQb3FMVkE/edit?usp=sharin... $ tar xf u-boot-a369-ipl.tar.bz2 $ cd u-boot-a369-ipl $ make
What I'm asking for, is can you upstream the a369evb board? In the README in board/... you should just document how to use it via QEMU. Thanks!

2013/12/10 Tom Rini trini@ti.com:
On Mon, Dec 09, 2013 at 04:07:29PM +0800, Kuo-Jung Su wrote:
2013/12/6 Tom Rini trini@ti.com:
On Wed, Dec 04, 2013 at 11:50:48AM +0800, Kuo-Jung Su wrote:
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
Can you provide an example user of this functionality? Thanks.
-- Tom
If you're looking for a real device, unfortunately there is no such device right now, it's a shiny new design which just came out last week.
If you're looking for a way for verification:
A real device with a NOR flash for ROM emulation. (e.g., Faraday A369 EVB)
A virtual device emulator. (e.g., Qemu)
This is the best option for you, the Qemu model for Faraday A369 is
available at my github account. Please use the command bellow to grab the source tree if necessary.
$ git clone -b qemu-1.5.1 https://github.com/dantesu1218/qemu.git $ cd qemu $ ./configure --target-list=arm-softmmu $ make
The example IPL code for the up-coming Faraday A369 U-boot is also available:
$ git clone -b u-boot-2014.01 https://github.com/dantesu1218/u-boot.git $ cd u-boot $ make a369evb_ipl_config $ make
You could also directly grab the pre-built binaries for quick verification.
$ wget https://drive.google.com/file/d/0BwfiewvSmUgAMlBnUkZQb3FMVkE/edit?usp=sharin... $ tar xf u-boot-a369-ipl.tar.bz2 $ cd u-boot-a369-ipl $ make
What I'm asking for, is can you upstream the a369evb board? In the README in board/... you should just document how to use it via QEMU. Thanks!
Got it, thanks.
I will make it a part of Faraday A36x patch series, and resend it later.
participants (2)
-
Kuo-Jung Su
-
Tom Rini