Juan_David
Juan_David

Reputation: 136

linking newlib nano with arm-none-eabi gnu toolchain: undefined reference to __libc_init_array

Even though I have scrolled through another similar post regarding this topic, I have not yet managed to solve my issue.

I'm working on a bare metal development approach for stm32f411RE and I just got through the need of using embedded standard libraries (newlib nano) so then I proceeded to linking it to my project as well as as calling __libc_init_array() before main() in my Reset_Handler for the propper initialization of the standard library functions and here is where the problem arises.

Roughly speaking(pseudocode you might think) my startup file is as follows:

//Function prototypes
//main and Reset_Handler need to be inside extern 
//in order to be recognized at the vector table

extern "C"{

    int main(void);
    void Reset_Handler(void);
    void __libc_init_array(void);

}


vector_table={

    (first address)STACK_POINTER,
    (second address)Reset_Handler,
            ...
        ISR routines

}

void Reset_Handler(void){

    //call to __libc_init_array in order to initialize standard libraries functions
    __libc_init_array();

    
    //starting point of the program
    main();
}

I get through the compilation and linking process successfully (no warnings, errors or anything) but the program fails to get to the main() function when I try to run it, in other words, it gets stuck at __libc_init_array();

When I run a debug session and look at the call stack this is what I get:

??@0xfffffce0 (Unknown Source:0)
<signal handler called>@0xfffffff9 (Unknown Source:0)
??@0x00000024 (Unknown Source:0)

And the program has not even reached main(). I guess it is obvious to say that setting a breakpoint is useless since the program does not even reaches main().

If I take __libc_init_array() out of the extern "C" I get the "__libc_init_array undefined reference" compilation error.

It is worth to say that my linker script as well as the startup and makefile were working like a charm on the bare metal approach, so the problem is not there, I mean, I just need to consider the appropriated flags for the linking process.

My project's structure is as following:

/My_project
  -main.cpp
  -file1.cpp
  -file2.cpp
  -startup_file.cpp
  -linker_script.ld
  -Makefile
  -syscalls.c (requiered for newlib nano)

I'm building the object files with:

arm-none-eabi-g++ -c -mcpu=cortex-m4 -std=c++11 -o0 -fno-exceptions

with the exception of building syscall.c with:

arm-none-eabi-gcc -c -mcpu=cortex-m4 -std=c11 -o0 -fno-exceptions

then linking all the object files with:

-T stm32_ls.ld --specs=nano.specs -Wl, -Map=final.map

Here is the map after the linking:

Archive member included to satisfy reference by file (symbol)

/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-errno.o)
                              syscalls.o (__errno)
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-exit.o)
                              /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o (exit)
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-impure.o)
                              /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-exit.o) (_global_impure_ptr)
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-init.o)
                              /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o (__libc_init_array)
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-memset.o)
                              /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o (memset)

Memory Configuration

Name             Origin             Length             Attributes
FLASH            0x0000000008000000 0x0000000000080000 xr
SRAM             0x0000000020000000 0x0000000000020000 xrw
*default*        0x0000000000000000 0xffffffffffffffff

Linker script and memory map

LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crti.o
LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o
LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o
LOAD stm32_startup.o
LOAD main.o
LOAD CONFIG.o
LOAD GPIO.o
LOAD LCD_16x2.o
LOAD USER_FUNCTIONS.o
LOAD syscalls.o
LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libstdc++_nano.a
LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libm.a
START GROUP
LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/libgcc.a
LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a
END GROUP
START GROUP
LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/libgcc.a
LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a
END GROUP
LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtend.o
LOAD /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtn.o

.text           0x0000000008000000     0x1008
 *(.isr_vector)
 .isr_vector    0x0000000008000000      0x198 stm32_startup.o
 *(.text)
 .text          0x0000000008000198        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crti.o
 .text          0x0000000008000198       0x70 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o
 .text          0x0000000008000208      0x138 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o
                0x0000000008000208                _stack_init
                0x0000000008000290                _mainCRTStartup
                0x0000000008000290                _start
 .text          0x0000000008000340       0x90 stm32_startup.o
                0x0000000008000340                Reset_Handler
                0x00000000080003c8                Default_Handler
                0x00000000080003c8                EXTI0_IRQHandler()
 .text          0x00000000080003d0      0x124 main.o
                0x00000000080003d0                enable_interrupt(IRQn_Struct)
                0x0000000008000400                disable_interrupt(IRQn_Struct)
                0x0000000008000434                EXTI15_10_IRQHandler()
                0x0000000008000468                main
                0x00000000080004a8                adc1_read()
                0x00000000080004d8                adc1_start_convertion()
 .text          0x00000000080004f4      0x24c CONFIG.o
                0x00000000080004f4                system_clock_settings(char, boolean)
                0x0000000008000630                EXTI_C13_config()
                0x0000000008000684                ADC_PA1_Config()
                0x00000000080006d8                HighSpeedConfig()
                0x0000000008000704                TIM10_config_init()
 .text          0x0000000008000740      0x56c GPIO.o
                0x0000000008000740                GPIO_PORT::GPIO_PORT(char, int, int)
                0x0000000008000740                GPIO_PORT::GPIO_PORT(char, int, int)
                0x0000000008000778                GPIO_PORT::GPIO_PORT(char, int, int, int)
                0x0000000008000778                GPIO_PORT::GPIO_PORT(char, int, int, int)
                0x00000000080007b0                GPIO_PORT::set_pin_status(int)
                0x0000000008000812                GPIO_PORT::read_pin_status()
                0x0000000008000856                GPIO_PORT::toggle_pin_status()
                0x0000000008000882                GPIO_PORT::pupd_selection(int)
                0x0000000008000950                GPIO_PORT::pin_mode_input()
                0x00000000080009aa                GPIO_PORT::pin_mode_output()
                0x0000000008000a04                GPIO_PORT::set_config()
                0x0000000008000b3a                GPIO_PORT::voltage_regulator_config()
                0x0000000008000b5c                GPIO_PORT::AHB1_clock_enable()
                0x0000000008000bf4                GPIO_PORT::gpio_register_selector()
 .text          0x0000000008000cac        0x0 LCD_16x2.o
 .text          0x0000000008000cac      0x110 USER_FUNCTIONS.o
                0x0000000008000cac                delay_ms(int)
                0x0000000008000d10                delay_us(int)
                0x0000000008000d70                power(int, int)
 .text          0x0000000008000dbc      0x202 syscalls.o
                0x0000000008000dbc                initialise_monitor_handles
                0x0000000008000dc8                _getpid
                0x0000000008000dd6                _kill
                0x0000000008000df6                _exit
                0x0000000008000e0a                _read
                0x0000000008000e44                _write
                0x0000000008000e7c                _close
                0x0000000008000e92                _fstat
                0x0000000008000eb0                _isatty
                0x0000000008000ec4                _lseek
                0x0000000008000edc                _open
                0x0000000008000ef6                _wait
                0x0000000008000f14                _unlink
                0x0000000008000f32                _times
                0x0000000008000f48                _stat
                0x0000000008000f66                _link
                0x0000000008000f86                _fork
                0x0000000008000f9c                _execve
 .text          0x0000000008000fbe        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-errno.o)
 .text          0x0000000008000fbe        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-exit.o)
 .text          0x0000000008000fbe        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-impure.o)
 .text          0x0000000008000fbe        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-init.o)
 .text          0x0000000008000fbe        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-memset.o)
 .text          0x0000000008000fbe        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtend.o
 .text          0x0000000008000fbe        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtn.o
 *(.rodata)
 *fill*         0x0000000008000fbe        0x2 
 .rodata        0x0000000008000fc0       0x24 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o
 .rodata        0x0000000008000fe4       0x24 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtend.o
                0x0000000008001008                . = ALIGN (0x4)
                0x0000000008001008                _etext = .

.glue_7         0x0000000008001008        0x0
 .glue_7        0x0000000008001008        0x0 linker stubs

.glue_7t        0x0000000008001008        0x0
 .glue_7t       0x0000000008001008        0x0 linker stubs

.vfp11_veneer   0x0000000008001008        0x0
 .vfp11_veneer  0x0000000008001008        0x0 linker stubs

.v4_bx          0x0000000008001008        0x0
 .v4_bx         0x0000000008001008        0x0 linker stubs

.init           0x0000000008001008       0x18
 .init          0x0000000008001008        0xc /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crti.o
                0x0000000008001008                _init
 .init          0x0000000008001014        0xc /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtn.o

.fini           0x0000000008001020       0x18
 .fini          0x0000000008001020        0xc /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crti.o
                0x0000000008001020                _fini
 .fini          0x000000000800102c        0xc /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtn.o

.iplt           0x0000000008001038        0x0
 .iplt          0x0000000008001038        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o

.text.__errno   0x0000000008001038       0x10
 .text.__errno  0x0000000008001038       0x10 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-errno.o)
                0x0000000008001038                __errno

.text.exit      0x0000000008001048       0x40
 .text.exit     0x0000000008001048       0x40 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-exit.o)
                0x0000000008001048                exit

.text.__libc_init_array
                0x0000000008001088       0x80
 .text.__libc_init_array
                0x0000000008001088       0x80 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-init.o)
                0x0000000008001088                __libc_init_array

.text.memset    0x0000000008001108       0x18
 .text.memset   0x0000000008001108       0x18 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-memset.o)
                0x0000000008001108                memset

.eh_frame       0x0000000008001120        0x4
 .eh_frame      0x0000000008001120        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o
 .eh_frame      0x0000000008001120        0x4 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtend.o

.ARM.extab      0x0000000008001124        0x0
 .ARM.extab     0x0000000008001124        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o

.ARM.exidx      0x0000000008001124        0x8
 .ARM.exidx     0x0000000008001124        0x8 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o
                                         0x10 (size before relaxing)

.rodata._global_impure_ptr
                0x000000000800112c        0x4
 .rodata._global_impure_ptr
                0x000000000800112c        0x4 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-impure.o)
                0x000000000800112c                _global_impure_ptr

.rel.dyn        0x0000000008001130        0x0
 .rel.iplt      0x0000000008001130        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o

.data           0x0000000020000000        0x8 load address 0x0000000008001130
                0x0000000020000000                _sdata = .
 *(.data)
 .data          0x0000000020000000        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crti.o
 .data          0x0000000020000000        0x4 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o
                0x0000000020000000                __dso_handle
 .data          0x0000000020000004        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o
 .data          0x0000000020000004        0x0 stm32_startup.o
 .data          0x0000000020000004        0x0 main.o
 .data          0x0000000020000004        0x0 CONFIG.o
 .data          0x0000000020000004        0x0 GPIO.o
 .data          0x0000000020000004        0x0 LCD_16x2.o
 .data          0x0000000020000004        0x0 USER_FUNCTIONS.o
 .data          0x0000000020000004        0x4 syscalls.o
                0x0000000020000004                environ
 .data          0x0000000020000008        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-errno.o)
 .data          0x0000000020000008        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-exit.o)
 .data          0x0000000020000008        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-impure.o)
 .data          0x0000000020000008        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-init.o)
 .data          0x0000000020000008        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-memset.o)
 .data          0x0000000020000008        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtend.o
 .data          0x0000000020000008        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtn.o
                0x0000000020000008                . = ALIGN (0x4)
                0x0000000020000008                _edata = .

.init_array     0x0000000020000008        0x4 load address 0x0000000008001138
 .init_array    0x0000000020000008        0x4 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o

.fini_array     0x000000002000000c        0x4 load address 0x000000000800113c
 .fini_array    0x000000002000000c        0x4 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o

.igot.plt       0x0000000020000010        0x0 load address 0x0000000008001140
 .igot.plt      0x0000000020000010        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o

.data._impure_ptr
                0x0000000020000010        0x4 load address 0x0000000008001140
 .data._impure_ptr
                0x0000000020000010        0x4 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-impure.o)
                0x0000000020000010                _impure_ptr

.data.impure_data
                0x0000000020000014       0x60 load address 0x0000000008001144
 .data.impure_data
                0x0000000020000014       0x60 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-impure.o)

.bss            0x0000000020000074       0x24 load address 0x00000000080011a4
                0x0000000020000074                _sbss = .
                0x0000000020000074                __bss_start__ = _sbss
 *(.bss)
 .bss           0x0000000020000074        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crti.o
 .bss           0x0000000020000074       0x1c /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtbegin.o
 .bss           0x0000000020000090        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o
 .bss           0x0000000020000090        0x0 stm32_startup.o
 .bss           0x0000000020000090        0x2 main.o
                0x0000000020000090                sensor_value
 .bss           0x0000000020000092        0x0 CONFIG.o
 .bss           0x0000000020000092        0x0 GPIO.o
 .bss           0x0000000020000092        0x0 LCD_16x2.o
 .bss           0x0000000020000092        0x0 USER_FUNCTIONS.o
 *fill*         0x0000000020000092        0x2 
 .bss           0x0000000020000094        0x4 syscalls.o
                0x0000000020000094                __env
 .bss           0x0000000020000098        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-errno.o)
 .bss           0x0000000020000098        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-exit.o)
 .bss           0x0000000020000098        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-impure.o)
 .bss           0x0000000020000098        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-init.o)
 .bss           0x0000000020000098        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-memset.o)
 .bss           0x0000000020000098        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtend.o
 .bss           0x0000000020000098        0x0 /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/crtn.o
                0x0000000020000098                _ebss = .
                0x0000000020000098                __bss_end__ = _ebss
                0x0000000020000098                . = ALIGN (0x4)
                0x0000000020000098                end = .
OUTPUT(final.elf elf32-littlearm)
LOAD linker stubs

I'm guessing, out of my ignorace, that name mangling is not the problem since __libc_init_array() is defined inside extern "C". Also, in the map file, I see only one symbol with the name __libc_init_array and it seems to be at the correct flash address.

Comments are valuable. Thanks for reading such a long post.

PD: linker script for whoever wants to read it:

ENTRY(Reset_Handler)

MEMORY
{
    FLASH(rx):ORIGIN =0x08000000,LENGTH =512K
    SRAM(rwx):ORIGIN =0x20000000,LENGTH =128K
}

SECTIONS
{
    .text :
    {
        *(.isr_vector)
        *(.text) 
        *(.rodata)
        . = ALIGN(4);
        _etext = .; /*end of section .text address*/
    }>FLASH 
    
    .data :
    {   
        _sdata = .; 
        *(.data)
        . = ALIGN(4);
        _edata = .;
    }>SRAM AT> FLASH
    
    .bss :
    {
        _sbss = .;
        __bss_start__ = _sbss;
        *(.bss)
        _ebss = .;
        __bss_end__ = _ebss;
        . = ALIGN(4);
        end = .;
    }>SRAM

}

startup file:

#include <stdint.h>


/**aliased and external defined functions get their names mangled
*so one needs to avoid name mangling by treating those functions
*as if they were compiled in C.Thats done by extern **/ 
extern "C"{

int main(void);
void Reset_Handler(void);
void Default_Handler(void);
void __libc_init_array(void);

} 

#define SRAM_START      0x20000000
#define SRAM_SIZE       (128U*1024U)    //128*1Kb 
#define SRAM_END        ((SRAM_START) + (SRAM_SIZE))
#define STACK_START     SRAM_END

extern uint32_t _etext;
extern uint32_t _sdata;
extern uint32_t _edata;
extern uint32_t _sbss;
extern uint32_t _ebss;

//function prototyping
//function prototyping


__attribute__((weak, alias("Default_Handler")))void EXTI0_IRQHandler(void);
__attribute__((weak, alias("Default_Handler")))void EXTI15_10_IRQHandler(void);


uint32_t(* const vectors[]) __attribute__((section(".isr_vector"))) ={
       
    (uint32_t*)STACK_START,                         /* 0x000 Stack Pointer */
    (uint32_t*)Reset_Handler,                       /* 0x004 Reset */
};

void Reset_Handler(void)
{    
   //copy .data section to SRAM
    uint32_t size = (uint32_t)&_edata - (uint32_t)&_sdata;
    
    uint8_t *pDst = (uint8_t*)&_sdata; //sram
    uint8_t *pSrc = (uint8_t*)&_etext; //source point comes from flash memory that is end of flash 
    
    for(uint32_t i =0 ; i < size ; i++)
    {
        *pDst++ = *pSrc++;
    }
    
    //copy .bss section to SRAM
    size = (uint32_t)&_ebss - (uint32_t)&_sbss;
    
    pDst = (uint8_t*)&_sbss; //sram
    
    for(uint32_t i =0 ; i < size ; i++)
    {
        *pDst++ = 0;
    }
    __libc_init_array();
    main();

}

void Default_Handler(void)
{
    while(1);
}

Upvotes: 1

Views: 4881

Answers (1)

Tom V
Tom V

Reputation: 5510

First of all, __libc_init_array() belongs inside extern "C". The map file you have above has it correct: it gets pulled in from libc_nano.a(lib_a-init.o).

This is not really the problem though. In your vector table, you have Reset_Handler where you should have the initial value of the stack pointer, and main where you should have the reset handler. main should never be in the vector, it is called by the reset handler as a normal function, not through the vector.

The crash you are having is most likely because you don't have a correct stack pointer, and the code is trying to use the stack.

Also, the first thing you do in your reset handler is call __libc_init_array. This is wrong. You need to (at least) copy the initialized data and zero the bss section first. If you are following the CMSIS pattern then you also need to call SystemInit. See the sample startup code and linker scripts in the STM32CubeF4 package.

EDIT: The above problems are in your pseudocode; the code doesn't match the pseudocode and doesn't have the above problems.

The next problem is that you have deleted half of the standard linker script. Try looking at the source of __libc_init_array to see what it needs. It needs the init array sections etc.

Here is an example with them in:

.init :
{
  KEEP (*(SORT_NONE(.init)))
}
>FLASH

.text :
{
  *(.text .text.* .stub .gnu.linkonce.t.*)
}
>FLASH

.fini :
{
  KEEP (*(SORT_NONE(.fini)))
}
>FLASH

.preinit_array :
{
  PROVIDE_HIDDEN (__preinit_array_start = .);
  KEEP (*(.preinit_array))
  PROVIDE_HIDDEN (__preinit_array_end = .);
}
>FLASH

.init_array :
{
  PROVIDE_HIDDEN (__init_array_start = .);
  KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
  KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
  PROVIDE_HIDDEN (__init_array_end = .);
}
>FLASH

.fini_array :
{
  PROVIDE_HIDDEN (__fini_array_start = .);
  KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
  KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
  PROVIDE_HIDDEN (__fini_array_end = .);
}
>FLASH

.ctors :
{
  KEEP (*crtbegin.o(.ctors))
  KEEP (*crtbegin?.o(.ctors))
  KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
  KEEP (*(SORT(.ctors.*)))
  KEEP (*(.ctors))
}
>FLASH

.dtors :
{
  KEEP (*crtbegin.o(.dtors))
  KEEP (*crtbegin?.o(.dtors))
  KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
  KEEP (*(SORT(.dtors.*)))
  KEEP (*(.dtors))
}
>FLASH

Upvotes: 1

Related Questions