From b7d01278b7092581ec774b7cf6185e04720a4c08 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 21 Nov 2015 15:24:55 +0000 Subject: Improved startup files for ARMCMx GCC, introduced support for RAM areas initialization. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8518 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s | 12 ++ os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s | 18 ++- os/common/ports/ARMCMx/compilers/GCC/crt1.c | 126 +++++++++++++++++ .../ARMCMx/compilers/GCC/ld/rules_STM32F7xx.ld | 150 +++++++++++++++++++-- os/common/ports/ARMCMx/compilers/GCC/rules.ld | 148 ++++++++++++++++++-- 5 files changed, 427 insertions(+), 27 deletions(-) (limited to 'os/common') diff --git a/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s b/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s index 51a79bb4f..c3ca9faa5 100644 --- a/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s +++ b/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s @@ -91,6 +91,13 @@ #define CRT0_INIT_BSS TRUE #endif +/** + * @brief RAM areas initialization switch. + */ +#if !defined(CRT0_INIT_RAM_AREAS) || defined(__DOXYGEN__) +#define CRT0_INIT_RAM_AREAS TRUE +#endif + /** * @brief Constructors invocation switch. */ @@ -204,6 +211,11 @@ bloop: endbloop: #endif +#if CRT0_INIT_RAM_AREAS == TRUE + /* RAM areas initialization.*/ + bl __init_ram_areas +#endif + /* Late initialization..*/ bl __late_init diff --git a/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s b/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s index 4812a29fe..c7792f954 100644 --- a/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +++ b/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s @@ -110,6 +110,13 @@ #define CRT0_INIT_BSS TRUE #endif +/** + * @brief RAM areas initialization switch. + */ +#if !defined(CRT0_INIT_RAM_AREAS) || defined(__DOXYGEN__) +#define CRT0_INIT_RAM_AREAS TRUE +#endif + /** * @brief Constructors invocation switch. */ @@ -246,9 +253,9 @@ psloop: #if CRT0_INIT_DATA == TRUE /* Data initialization. Note, it assumes that the DATA size is a multiple of 4 so the linker file must ensure this.*/ - ldr r1, =_textdata - ldr r2, =_data - ldr r3, =_edata + ldr r1, =_textdata_start + ldr r2, =_data_start + ldr r3, =_data_end dloop: cmp r2, r3 ittt lo @@ -270,6 +277,11 @@ bloop: blo bloop #endif +#if CRT0_INIT_RAM_AREAS == TRUE + /* RAM areas initialization.*/ + bl __init_ram_areas +#endif + /* Late initialization..*/ bl __late_init diff --git a/os/common/ports/ARMCMx/compilers/GCC/crt1.c b/os/common/ports/ARMCMx/compilers/GCC/crt1.c index b20c3ba9a..c47214e39 100644 --- a/os/common/ports/ARMCMx/compilers/GCC/crt1.c +++ b/os/common/ports/ARMCMx/compilers/GCC/crt1.c @@ -29,6 +29,103 @@ #include "cmparams.h" +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +#if !defined(CRT1_AREAS_NUMBER) || defined(__DOXYGEN__) +#define CRT1_AREAS_NUMBER 8 +#endif + +#if (CRT1_AREAS_NUMBER < 0) || (CRT1_AREAS_NUMBER > 8) +#error "CRT1_AREAS_NUMBER must be within 0 and 8" +#endif + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/** + * @brief Type of an area to be initialized. + */ +typedef struct { + uint32_t *init_text_area; + uint32_t *init_area; + uint32_t *clear_area; + uint32_t *no_init_area; +} ram_init_area_t; + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +#if (CRT1_AREAS_NUMBER > 0) || defined(__DOXYGEN__) +extern uint32_t __ram0_init_text__, __ram0_init__, __ram0_clear__, __ram0_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 1) || defined(__DOXYGEN__) +extern uint32_t __ram1_init_text__, __ram1_init__, __ram1_clear__, __ram1_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 2) || defined(__DOXYGEN__) +extern uint32_t __ram2_init_text__, __ram2_init__, __ram2_clear__, __ram2_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 3) || defined(__DOXYGEN__) +extern uint32_t __ram3_init_text__, __ram3_init__, __ram3_clear__, __ram3_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 4) || defined(__DOXYGEN__) +extern uint32_t __ram4_init_text__, __ram4_init__, __ram4_clear__, __ram4_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 5) || defined(__DOXYGEN__) +extern uint32_t __ram5_init_text__, __ram5_init__, __ram5_clear__, __ram5_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 6) || defined(__DOXYGEN__) +extern uint32_t __ram6_init_text__, __ram6_init__, __ram6_clear__, __ram6_noinit__; +#endif +#if (CRT1_AREAS_NUMBER > 7) || defined(__DOXYGEN__) +extern uint32_t __ram7_init_text__, __ram7_init__, __ram7_clear__, __ram7_noinit__; +#endif + +/** + * @brief Static table of areas to be initialized. + */ +#if (CRT1_AREAS_NUMBER > 0) || defined(__DOXYGEN__) +static const ram_init_area_t ram_areas[CRT1_AREAS_NUMBER] = { + {&__ram0_init_text__, &__ram0_init__, &__ram0_clear__, &__ram0_noinit__}, +#if (CRT1_AREAS_NUMBER > 1) || defined(__DOXYGEN__) + {&__ram1_init_text__, &__ram1_init__, &__ram1_clear__, &__ram1_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 2) || defined(__DOXYGEN__) + {&__ram2_init_text__, &__ram2_init__, &__ram2_clear__, &__ram2_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 3) || defined(__DOXYGEN__) + {&__ram3_init_text__, &__ram3_init__, &__ram3_clear__, &__ram3_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 4) || defined(__DOXYGEN__) + {&__ram4_init_text__, &__ram4_init__, &__ram4_clear__, &__ram4_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 5) || defined(__DOXYGEN__) + {&__ram5_init_text__, &__ram5_init__, &__ram5_clear__, &__ram5_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 6) || defined(__DOXYGEN__) + {&__ram6_init_text__, &__ram6_init__, &__ram6_clear__, &__ram6_noinit__}, +#endif +#if (CRT1_AREAS_NUMBER > 7) || defined(__DOXYGEN__) + {&__ram7_init_text__, &__ram7_init__, &__ram7_clear__, &__ram7_noinit__}, +#endif +}; +#endif + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + /** * @brief Architecture-dependent core initialization. * @details This hook is invoked immediately after the stack initialization @@ -92,4 +189,33 @@ void __default_exit(void) { } } +/** + * @brief Performs the initialization of the various RAM areas. + */ +void __init_ram_areas(void) { + const ram_init_area_t *rap = ram_areas; + +#if CRT1_AREAS_NUMBER > 0 + do { + uint32_t *tp = rap->init_text_area; + uint32_t *p = rap->init_area; + + /* Copying initialization data.*/ + while (p < rap->clear_area) { + *p = *tp; + p++; + tp++; + } + + /* Zeroing clear area.*/ + while (p < rap->no_init_area) { + *p = 0; + p++; + } + rap++; + } + while (rap < &ram_areas[CRT1_AREAS_NUMBER]); +#endif +} + /** @} */ diff --git a/os/common/ports/ARMCMx/compilers/GCC/ld/rules_STM32F7xx.ld b/os/common/ports/ARMCMx/compilers/GCC/ld/rules_STM32F7xx.ld index 44ccf7bba..0035c7ac3 100644 --- a/os/common/ports/ARMCMx/compilers/GCC/ld/rules_STM32F7xx.ld +++ b/os/common/ports/ARMCMx/compilers/GCC/ld/rules_STM32F7xx.ld @@ -56,18 +56,18 @@ SECTIONS constructors : ALIGN(4) SUBALIGN(4) { - PROVIDE(__init_array_start = .); + __init_array_start = .; KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) - PROVIDE(__init_array_end = .); + __init_array_end = .; } > flash_itcm AT > flash destructors : ALIGN(4) SUBALIGN(4) { - PROVIDE(__fini_array_start = .); + __fini_array_start = .; KEEP(*(.fini_array)) KEEP(*(SORT(.fini_array.*))) - PROVIDE(__fini_array_end = .); + __fini_array_end = .; } > flash_itcm AT > flash .text : ALIGN(16) SUBALIGN(16) @@ -85,9 +85,9 @@ SECTIONS } > flash_itcm AT > flash .ARM.exidx : { - PROVIDE(__exidx_start = .); + __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) - PROVIDE(__exidx_end = .); + __exidx_end = .; } > flash_itcm AT > flash .eh_frame_hdr : @@ -110,16 +110,16 @@ SECTIONS .rodata : ALIGN(4) { . = ALIGN(4); - PROVIDE(__rodata_base__ = .); + __rodata_base__ = .; *(.rodata) *(.rodata.*) . = ALIGN(4); - PROVIDE(__rodata_end__ = .); + __rodata_end__ = .; } > flash + /* Legacy symbol, not used anywhere.*/ . = ALIGN(4); - _etext = .; - _textdata = _etext; + PROVIDE(_etext = .); /* Special section for exceptions stack.*/ .mstack : @@ -167,92 +167,216 @@ SECTIONS .data : ALIGN(4) { . = ALIGN(4); + PROVIDE(_textdata = LOADADDR(.data)); PROVIDE(_data = .); + _textdata_start = LOADADDR(.data); + _data_start = .; *(.data) *(.data.*) *(.ramtext) . = ALIGN(4); PROVIDE(_edata = .); + _data_end = .; } > DATA_RAM AT > flash - .bss : ALIGN(4) + .bss (NOLOAD) : ALIGN(4) { . = ALIGN(4); - PROVIDE(_bss_start = .); + _bss_start = .; *(.bss) *(.bss.*) *(COMMON) . = ALIGN(4); - PROVIDE(_bss_end = .); + _bss_end = .; PROVIDE(end = .); } > BSS_RAM + .ram0_init : ALIGN(4) + { + . = ALIGN(4); + __ram0_init_text__ = LOADADDR(.ram0_init); + __ram0_init__ = .; + *(.ram0_init) + *(.ram0_init.*) + . = ALIGN(4); + } > ram0 AT > flash + .ram0 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram0_clear__ = .; + *(.ram0_clear) + *(.ram0_clear.*) + . = ALIGN(4); + __ram0_noinit__ = .; *(.ram0) *(.ram0.*) . = ALIGN(4); __ram0_free__ = .; } > ram0 + .ram1_init : ALIGN(4) + { + . = ALIGN(4); + __ram1_init_text__ = LOADADDR(.ram1_init); + __ram1_init__ = .; + *(.ram1_init) + *(.ram1_init.*) + . = ALIGN(4); + } > ram1 AT > flash + .ram1 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram1_clear__ = .; + *(.ram1_clear) + *(.ram1_clear.*) + . = ALIGN(4); + __ram1_noinit__ = .; *(.ram1) *(.ram1.*) . = ALIGN(4); __ram1_free__ = .; } > ram1 + .ram2_init : ALIGN(4) + { + . = ALIGN(4); + __ram2_init_text__ = LOADADDR(.ram2_init); + __ram2_init__ = .; + *(.ram2_init) + *(.ram2_init.*) + . = ALIGN(4); + } > ram2 AT > flash + .ram2 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram2_clear__ = .; + *(.ram2_clear) + *(.ram2_clear.*) + . = ALIGN(4); + __ram2_noinit__ = .; *(.ram2) *(.ram2.*) . = ALIGN(4); __ram2_free__ = .; } > ram2 + .ram3_init : ALIGN(4) + { + . = ALIGN(4); + __ram3_init_text__ = LOADADDR(.ram3_init); + __ram3_init__ = .; + *(.ram3_init) + *(.ram3_init.*) + . = ALIGN(4); + } > ram3 AT > flash + .ram3 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram3_clear__ = .; + *(.ram3_clear) + *(.ram3_clear.*) + . = ALIGN(4); + __ram3_noinit__ = .; *(.ram3) *(.ram3.*) . = ALIGN(4); __ram3_free__ = .; } > ram3 + .ram4_init : ALIGN(4) + { + . = ALIGN(4); + __ram4_init_text__ = LOADADDR(.ram4_init); + __ram4_init__ = .; + *(.ram4_init) + *(.ram4_init.*) + . = ALIGN(4); + } > ram4 AT > flash + .ram4 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram4_clear__ = .; + *(.ram4_clear) + *(.ram4_clear.*) + . = ALIGN(4); + __ram4_noinit__ = .; *(.ram4) *(.ram4.*) . = ALIGN(4); __ram4_free__ = .; } > ram4 + .ram5_init : ALIGN(4) + { + . = ALIGN(4); + __ram5_init_text__ = LOADADDR(.ram5_init); + __ram5_init__ = .; + *(.ram5_init) + *(.ram5_init.*) + . = ALIGN(4); + } > ram5 AT > flash + .ram5 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram5_clear__ = .; + *(.ram5_clear) + *(.ram5_clear.*) + . = ALIGN(4); + __ram5_noinit__ = .; *(.ram5) *(.ram5.*) . = ALIGN(4); __ram5_free__ = .; } > ram5 + .ram6_init : ALIGN(4) + { + . = ALIGN(4); + __ram6_init_text__ = LOADADDR(.ram6_init); + __ram6_init__ = .; + *(.ram6_init) + *(.ram6_init.*) + . = ALIGN(4); + } > ram6 AT > flash + .ram6 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram6_clear__ = .; + *(.ram6_clear) + *(.ram6_clear.*) + . = ALIGN(4); + __ram6_noinit__ = .; *(.ram6) *(.ram6.*) . = ALIGN(4); __ram6_free__ = .; } > ram6 + .ram7_init : ALIGN(4) + { + . = ALIGN(4); + __ram7_init_text__ = LOADADDR(.ram7_init); + __ram7_init__ = .; + *(.ram7_init) + *(.ram7_init.*) + . = ALIGN(4); + } > ram7 AT > flash + .ram7 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram7_clear__ = .; + *(.ram7_clear) + *(.ram7_clear.*) + . = ALIGN(4); + __ram7_noinit__ = .; *(.ram7) *(.ram7.*) . = ALIGN(4); diff --git a/os/common/ports/ARMCMx/compilers/GCC/rules.ld b/os/common/ports/ARMCMx/compilers/GCC/rules.ld index 858039a89..deffc5fc6 100644 --- a/os/common/ports/ARMCMx/compilers/GCC/rules.ld +++ b/os/common/ports/ARMCMx/compilers/GCC/rules.ld @@ -56,18 +56,18 @@ SECTIONS constructors : ALIGN(4) SUBALIGN(4) { - PROVIDE(__init_array_start = .); + __init_array_start = .; KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) - PROVIDE(__init_array_end = .); + __init_array_end = .; } > flash destructors : ALIGN(4) SUBALIGN(4) { - PROVIDE(__fini_array_start = .); + __fini_array_start = .; KEEP(*(.fini_array)) KEEP(*(SORT(.fini_array.*))) - PROVIDE(__fini_array_end = .); + __fini_array_end = .; } > flash .text : ALIGN(16) SUBALIGN(16) @@ -87,9 +87,9 @@ SECTIONS } > flash .ARM.exidx : { - PROVIDE(__exidx_start = .); + __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) - PROVIDE(__exidx_end = .); + __exidx_end = .; } > flash .eh_frame_hdr : @@ -107,10 +107,11 @@ SECTIONS . = ALIGN(8); } > flash + /* Legacy symbol, not used anywhere.*/ . = ALIGN(4); - _etext = .; - _textdata = _etext; + PROVIDE(_etext = .); + /* Special section for exceptions stack.*/ .mstack : { . = ALIGN(8); @@ -120,6 +121,7 @@ SECTIONS __main_stack_end__ = .; } > MAIN_STACK_RAM + /* Special section for process stack.*/ .pstack : { __process_stack_base__ = .; @@ -133,92 +135,216 @@ SECTIONS .data : ALIGN(4) { . = ALIGN(4); + PROVIDE(_textdata = LOADADDR(.data)); PROVIDE(_data = .); + _textdata_start = LOADADDR(.data); + _data_start = .; *(.data) *(.data.*) *(.ramtext) . = ALIGN(4); PROVIDE(_edata = .); + _data_end = .; } > DATA_RAM AT > flash - .bss : ALIGN(4) + .bss (NOLOAD) : ALIGN(4) { . = ALIGN(4); - PROVIDE(_bss_start = .); + _bss_start = .; *(.bss) *(.bss.*) *(COMMON) . = ALIGN(4); - PROVIDE(_bss_end = .); + _bss_end = .; PROVIDE(end = .); } > BSS_RAM + .ram0_init : ALIGN(4) + { + . = ALIGN(4); + __ram0_init_text__ = LOADADDR(.ram0_init); + __ram0_init__ = .; + *(.ram0_init) + *(.ram0_init.*) + . = ALIGN(4); + } > ram0 AT > flash + .ram0 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram0_clear__ = .; + *(.ram0_clear) + *(.ram0_clear.*) + . = ALIGN(4); + __ram0_noinit__ = .; *(.ram0) *(.ram0.*) . = ALIGN(4); __ram0_free__ = .; } > ram0 + .ram1_init : ALIGN(4) + { + . = ALIGN(4); + __ram1_init_text__ = LOADADDR(.ram1_init); + __ram1_init__ = .; + *(.ram1_init) + *(.ram1_init.*) + . = ALIGN(4); + } > ram1 AT > flash + .ram1 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram1_clear__ = .; + *(.ram1_clear) + *(.ram1_clear.*) + . = ALIGN(4); + __ram1_noinit__ = .; *(.ram1) *(.ram1.*) . = ALIGN(4); __ram1_free__ = .; } > ram1 + .ram2_init : ALIGN(4) + { + . = ALIGN(4); + __ram2_init_text__ = LOADADDR(.ram2_init); + __ram2_init__ = .; + *(.ram2_init) + *(.ram2_init.*) + . = ALIGN(4); + } > ram2 AT > flash + .ram2 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram2_clear__ = .; + *(.ram2_clear) + *(.ram2_clear.*) + . = ALIGN(4); + __ram2_noinit__ = .; *(.ram2) *(.ram2.*) . = ALIGN(4); __ram2_free__ = .; } > ram2 + .ram3_init : ALIGN(4) + { + . = ALIGN(4); + __ram3_init_text__ = LOADADDR(.ram3_init); + __ram3_init__ = .; + *(.ram3_init) + *(.ram3_init.*) + . = ALIGN(4); + } > ram3 AT > flash + .ram3 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram3_clear__ = .; + *(.ram3_clear) + *(.ram3_clear.*) + . = ALIGN(4); + __ram3_noinit__ = .; *(.ram3) *(.ram3.*) . = ALIGN(4); __ram3_free__ = .; } > ram3 + .ram4_init : ALIGN(4) + { + . = ALIGN(4); + __ram4_init_text__ = LOADADDR(.ram4_init); + __ram4_init__ = .; + *(.ram4_init) + *(.ram4_init.*) + . = ALIGN(4); + } > ram4 AT > flash + .ram4 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram4_clear__ = .; + *(.ram4_clear) + *(.ram4_clear.*) + . = ALIGN(4); + __ram4_noinit__ = .; *(.ram4) *(.ram4.*) . = ALIGN(4); __ram4_free__ = .; } > ram4 + .ram5_init : ALIGN(4) + { + . = ALIGN(4); + __ram5_init_text__ = LOADADDR(.ram5_init); + __ram5_init__ = .; + *(.ram5_init) + *(.ram5_init.*) + . = ALIGN(4); + } > ram5 AT > flash + .ram5 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram5_clear__ = .; + *(.ram5_clear) + *(.ram5_clear.*) + . = ALIGN(4); + __ram5_noinit__ = .; *(.ram5) *(.ram5.*) . = ALIGN(4); __ram5_free__ = .; } > ram5 + .ram6_init : ALIGN(4) + { + . = ALIGN(4); + __ram6_init_text__ = LOADADDR(.ram6_init); + __ram6_init__ = .; + *(.ram6_init) + *(.ram6_init.*) + . = ALIGN(4); + } > ram6 AT > flash + .ram6 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram6_clear__ = .; + *(.ram6_clear) + *(.ram6_clear.*) + . = ALIGN(4); + __ram6_noinit__ = .; *(.ram6) *(.ram6.*) . = ALIGN(4); __ram6_free__ = .; } > ram6 + .ram7_init : ALIGN(4) + { + . = ALIGN(4); + __ram7_init_text__ = LOADADDR(.ram7_init); + __ram7_init__ = .; + *(.ram7_init) + *(.ram7_init.*) + . = ALIGN(4); + } > ram7 AT > flash + .ram7 (NOLOAD) : ALIGN(4) { . = ALIGN(4); + __ram7_clear__ = .; + *(.ram7_clear) + *(.ram7_clear.*) + . = ALIGN(4); + __ram7_noinit__ = .; *(.ram7) *(.ram7.*) . = ALIGN(4); -- cgit v1.2.3