了解C运行时环境(ARM) - 从哪里开始

ST *_*ade 8 c arm

我是主要使用ARM Cortex-M设备的嵌入式开发人员.最近我转向Linux并决定学习更多关于构建/汇编/链接过程,如何编写makefile等,因为我正在使用IDE(IAR,Keil,Eclipse等),其中许多东西是自动化的和用户实际上并不知道后台发生了什么.目标是更多地了解这个低级别流程,如何正确使用这些工具,而不仅仅依赖于IDE默认设置.

编写完makefile后,我能够构建我的应用程序.但是,我决定通过直接调用链接器(而不是通过编译器)手动执行链接过程,并且出现了令人惊讶的麻烦!未定义的libc引用,__ libc_init_array中的_init函数,_exit等是问题所在.经过一整天的调查,我能够手动包含所有目标文件(crt0.o,crti.o)和库(libnosys.a).显然,编译器会自动执行此操作.

在克服了这些麻烦之后,我想通了,我对这些内部结构一点都不了解.为什么我需要一些ctr0.o,crti.o等.那些来自等等.它是否链接到编译器/链接器或C运行时库或系统?

我想更多地了解这些内部结构,但是,我不确定,我实际上在寻找什么.它是一个库,系统,编译器吗?

我明白,系统(MCU)需要初始化RAM中的变量和其他东西,但是我错过了完整的图片.你能指导我读一本好书/手册,关于这些东西的读物吗?我到底在想什么?

编辑:

在与您讨论后,我很可能想出了我需要的东西,所以我会按照以下方式重新解释我的问题:

1)我收到了一个MCU(假设是STM32F4xx),我应该创建一个闪烁的LED示例.所有这些都应该从头开始,自己的启动代码,没有使用外部库等.

2)在第二步中,有人告诉我所有这些已经由其他人完成(GCC工具链/标准库,MCU供应商启动文件等).所以我只需要理解/链接我的工作与完成的工作并比较差异,为什么他们这样做等等.

所有这些都是由@mbjoe回答+我发现了一些有趣的阅读:https://www.amazon.com/Embedded-Shoestring-experience-designing-software/dp/0750676094

感谢大家的帮助,并以正确的方式指导我!

mbj*_*joe 3

您所指的模块(ctr0.o、crti.o、_init、__libc_init_array、_exit)是 IAR 和/或 Keil 预构建的库/目标文件/函数。正如您所说,在运行 main() 函数之前,需要它们来初始化环境(全局变量初始化、中断向量表等)。

在这些库/目标文件中的某个时刻,C 或汇编语言中将会有一个如下所示的函数:

void startup(void)
{ 
    ... init code ...

    main();

    while(1);   // or _exit()
}
Run Code Online (Sandbox Code Playgroud)

您可以查看这些从头开始构建启动代码的示例:

http://www.embedded.com/design/mcus-processors-and-socs/4007119/Building-Bare-Metal-ARM-Systems-with-GNU-Part-1--入门

https://github.com/payne92/bare-metal-arm