为什么需要链接描述文件和启动代码?

dvn*_*zzz 2 embedded gcc startup linker-scripts

我已经阅读了本教程

我可以按照指南并运行代码。但是我有疑问。

1)为什么我们既需要加载地址又需要运行时地址。据我了解,这是因为我们也将.data放入了闪存;那么为什么我们不在那里运行应用程序,却需要启动代码将其复制到RAM?

http://www.bravegnu.org/gnu-eprog/c-startup.html

2)为什么我们在这里需要链接脚本和启动代码。我不仅可以按以下方式构建C源并使用qemu运行它吗?

arm-none-eabi-gcc -nostdlib -o sum_array.elf sum_array.c
Run Code Online (Sandbox Code Playgroud)

非常感谢

old*_*mer 5

指南中回答了您的第一个问题。

在操作系统上加载程序时,.data节(基本上是非零的全局变量)将从“二进制”加载到内存中的正确偏移量中,以便在程序启动时,代表变量的那些内存位置具有这些价值观。

unsigned int x=5;
unsigned int y;
Run Code Online (Sandbox Code Playgroud)

作为C程序员,您编写了上面的代码,当您初次使用x时期望x为5是吗?好吧,如果要从闪存,裸机启动,则您没有操作系统可以为您将该值复制到ram中,因此必须有人来做。此外,所有.data内容都必须位于flash中,数字5必须位于flash中的某个位置,以便可以将其复制到ram中。因此,您需要一个闪存地址和一个ram地址。同一件事的两个地址。

这就开始回答您的第二个问题,对于您编写的每行C代码,您都假设诸如任何函数都可以调用任何其他函数之类的事情。您希望能够调用函数吗?并且您希望能够具有局部变量,并且希望上面的变量x为5,并且您可能会假设y为零,尽管幸运的是,编译器已开始对此发出警告。通用C的启动代码至少要设置堆栈指针,该堆栈指针允许您调用其他函数并具有局部变量,并且函数的长度超过一两行代码,它将.bss置零,从而使上面的y变量为零,它将值5复制到ram上,以便在运行入口点C函数的代码时x可以使用。

如果您没有操作系统,那么您必须具有执行此操作的代码,是的,为已经具有启动和链接程序脚本的各种平台设置了许多许多沙箱和工具链,因此您可以

gcc -O myprog.elf myprog.c 
Run Code Online (Sandbox Code Playgroud)

现在,这并不意味着您可以不使用... system ... printf,fopen等进行系统调用。但是,如果下载这些工具链之一,则意味着您实际上不必编写链接程序脚本或引导程序。

但是它仍然是有价值的信息,请注意,基于操作系统的程序也需要启动代码和链接脚本,这只是操作系统的本机编译器假定您将主要为该操作系统编写程序,并且结果,它们在该工具链中提供了链接程序脚本和启动代码。