将 newlib nano 与 arm-none-eabi gnu 工具链链接:未定义对 __libc_init_array 的引用

Posted

技术标签:

【中文标题】将 newlib nano 与 arm-none-eabi gnu 工具链链接:未定义对 __libc_init_array 的引用【英文标题】:linking newlib nano with arm-none-eabi gnu toolchain: undefined reference to __libc_init_array 【发布时间】:2022-01-14 14:21:51 【问题描述】:

尽管我浏览过另一篇关于此主题的类似帖子,但我还没有设法解决我的问题。

我正在为 stm32f411RE 开发裸机开发方法,我刚刚解决了使用嵌入式标准库 (newlib nano) 的需要,所以我开始将它链接到我的项目以及之前调用 __libc_init_array()我的 Reset_Handler 中的 main() 用于标准库函数的propper初始化,这就是问题出现的地方。

粗略地说(你可能认为的伪代码)我的启动文件如下:

//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();

我成功地完成了编译和链接过程(没有警告、错误或任何东西),但是当我尝试运行它时程序无法访问 main() 函数,换句话说,它卡在了 __libc_init_array() ;

当我运行调试会话并查看调用堆栈时,这就是我得到的:

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

而且程序甚至还没有到达 main()。我想很明显,设置断点是没有用的,因为程序甚至没有到达 main()。

如果我将 __libc_init_array() 从外部“C”中取出,则会出现“__libc_init_array 未定义引用”编译错误。

值得一提的是,我的链接器脚本以及启动和生成文件在裸机方法上的工作就像一个魅力,所以问题不存在,我的意思是,我只需要考虑为链接过程。

我的项目结构如下:

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

我正在构建目标文件:

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

除了构建 syscall.c 之外:

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

然后将所有目标文件链接到:

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

链接后的地图如下:

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

我猜,出于我的无知,名称修改不是问题,因为 __libc_init_array() 是在 extern "C" 中定义的。此外,在映射文件中,我只看到一个名为 __libc_init_array 的符号,而且它似乎位于正确的闪存地址。

评论很有价值。感谢您阅读这么长的帖子。

PD:任何想阅读它的人的链接器脚本:

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


启动文件:

#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);

【问题讨论】:

【参考方案1】:

首先,__libc_init_array() 属于内部 extern "C"。您上面的地图文件是正确的:它是从libc_nano.a(lib_a-init.o) 中提取的。

但这并不是真正的问题。在你的向量表中,你有Reset_Handler,你应该有堆栈指针的初始值,还有main,你应该有重置处理程序。 main 永远不应该在向量中,它由重置处理程序作为普通函数调用,而不是通过向量。

您遇到的崩溃很可能是因为您没有正确的堆栈指针,并且代码正在尝试使用堆栈。

此外,您在重置处理程序中做的第一件事是调用__libc_init_array。这是错误的。您需要(至少)复制初始化数据并首先将 bss 部分归零。如果您遵循 CMSIS 模式,那么您还需要致电 SystemInit。请参阅STM32CubeF4 包中的示例启动代码和链接器脚本。

编辑:以上问题在你的伪代码中;代码与伪代码不匹配,不存在上述问题。

下一个问题是您已经删除了一半的标准链接描述文件。尝试查看__libc_init_array 的来源,看看它需要什么。它需要初始化数组部分等。

以下是它们的示例:

.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

【讨论】:

我说那是伪代码。在帖子的末尾,我放置了与您描述的完全一样的启动文件。请看一看。

以上是关于将 newlib nano 与 arm-none-eabi gnu 工具链链接:未定义对 __libc_init_array 的引用的主要内容,如果未能解决你的问题,请参考以下文章

如何使用QEMU运行Newlib应用程序?

Jetson nano开发笔记jetson nano 环境搭建与常见软件安装

为我的操作系统移植NewLib:一些问题

关于 FreeRTOS和 newlib库共存问题

关于 FreeRTOS和 newlib库共存问题

关于 FreeRTOS和 newlib库共存问题