[M2351] Support initializing multiple .data/.bss sections with GCC_ARM

pull/10959/head
ccli8 2019-01-16 13:18:35 +08:00 committed by Chun-Chieh Li
parent db11eef0bc
commit 76a029e88d
2 changed files with 61 additions and 20 deletions

View File

@ -150,6 +150,23 @@ SECTIONS
. = ALIGN(8); . = ALIGN(8);
} > VECTORS } > VECTORS
.copy.table : ALIGN(4)
{
__copy_table_start__ = .;
LONG (LOADADDR(.data))
LONG (ADDR(.data))
LONG (SIZEOF(.data))
__copy_table_end__ = .;
} > FLASH
.zero.table : ALIGN(4)
{
__zero_table_start__ = .;
LONG (ADDR(.bss))
LONG (SIZEOF(.bss))
__zero_table_end__ = .;
} > FLASH
.text : .text :
{ {
*(.text*) *(.text*)

View File

@ -55,11 +55,10 @@ extern void __main(void);
void __iar_program_start(void); void __iar_program_start(void);
#elif defined(__GNUC__) #elif defined(__GNUC__)
extern uint32_t __StackTop; extern uint32_t __StackTop;
extern uint32_t __etext; extern uint32_t __copy_table_start__;
extern uint32_t __data_start__; extern uint32_t __copy_table_end__;
extern uint32_t __data_end__; extern uint32_t __zero_table_start__;
extern uint32_t __bss_start__; extern uint32_t __zero_table_end__;
extern uint32_t __bss_end__;
#if defined(TOOLCHAIN_GCC_ARM) #if defined(TOOLCHAIN_GCC_ARM)
extern void _start(void); extern void _start(void);
@ -350,25 +349,50 @@ void Reset_Handler(void)
__iar_program_start(); __iar_program_start();
#elif defined(__GNUC__) #elif defined(__GNUC__)
uint32_t *src_ind = (uint32_t *) &__etext; /* Move (multiple) .data section(s) from ROM to RAM */
uint32_t *dst_ind = (uint32_t *) &__data_start__; {
uint32_t *dst_end = (uint32_t *) &__data_end__; /* Struct of copy table entry which must match linker script */
typedef struct copy_table_entry_ {
uint32_t src; // Address to copy from
uint32_t dst; // Address to copy to
uint32_t size; // Copy size in bytes
} copy_table_entry;
/* Move .data section from ROM to RAM */ copy_table_entry *copy_table_ind = (copy_table_entry *) &__copy_table_start__;
copy_table_entry *copy_table_end = (copy_table_entry *) &__copy_table_end__;
for (; copy_table_ind != copy_table_end; copy_table_ind ++) {
uint32_t *src_ind = (uint32_t *) copy_table_ind->src;
uint32_t *src_end = (uint32_t *) (copy_table_ind->src + copy_table_ind->size);
uint32_t *dst_ind = (uint32_t *) copy_table_ind->dst;
if (src_ind != dst_ind) { if (src_ind != dst_ind) {
for (; dst_ind < dst_end;) { for (; src_ind < src_end;) {
*dst_ind ++ = *src_ind ++; *dst_ind ++ = *src_ind ++;
} }
} }
}
}
/* Initialize (multiple) .bss sections to zero */
{
/* Struct of zero table entry which must match linker script */
typedef struct zero_table_entry_ {
uint32_t start; // Address to start zero'ing
uint32_t size; // Zero size in bytes
} zero_table_entry;
zero_table_entry *zero_table_ind = (zero_table_entry *) &__zero_table_start__;
zero_table_entry *zero_table_end = (zero_table_entry *) &__zero_table_end__;
for (; zero_table_ind != zero_table_end; zero_table_ind ++) {
uint32_t *dst_ind = (uint32_t *) zero_table_ind->start;
uint32_t *dst_end = (uint32_t *) (zero_table_ind->start + zero_table_ind->size);
/* Initialize .bss section to zero */
dst_ind = (uint32_t *) &__bss_start__;
dst_end = (uint32_t *) &__bss_end__;
if (dst_ind != dst_end) {
for (; dst_ind < dst_end; ) { for (; dst_ind < dst_end; ) {
*dst_ind ++ = 0; *dst_ind ++ = 0;
} }
} }
}
_start(); _start();