问题描述
当使用 gnu 工具链,特别是 arm-none-eabi 时,是否有任何原因为什么在使用命令行链接器选项时,它会求助于“main”开头的似乎不正确的地址。然而,当“main”是其他任何东西时,正确的起始地址和堆栈被初始化。例如,
.thumb
.Syntax unified
.globl _start
_start:
.word 0x20001000
.word reset
reset:
bl main
b .
int main ( void )
{
return(0);
}
arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-as start.s -o start.o
arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-ld -Ttext=0x08000000 start.o main.o -o main.elf
arm-none-eabi-objdump -d main.elf
main.elf: file format elf32-littlearm
disassembly of section .text:
08000000 <main>:
8000000: 2000 movs r0,#0
8000002: 4770 bx lr
08000004 <_start>:
8000004: 20001000 .word 0x20001000
8000008: 0800000c .word 0x0800000c
0800000c <reset>:
800000c: f7ff fff8 bl 8000000 <main>
8000010: e7fe b.n 8000010 <reset+0x4>
在反汇编中,上面的输出没有根据我的注意正确初始化堆栈 0x20001000
和 rom 0x08000000
的开始,但是..
.thumb
.Syntax unified
.globl _start
_start:
.word 0x20001000
.word reset
reset:
bl notmain
b .
int notmain ( void )
{
return(0);
}
arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-as start.s -o start.o
arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-ld -Ttext=0x08000000 start.o main.o -o main.elf
arm-none-eabi-objdump -d main.elf
main.elf: file format elf32-littlearm
disassembly of section .text:
08000000 <_start>:
8000000: 20001000 .word 0x20001000
8000004: 08000008 .word 0x08000008
08000008 <reset>:
8000008: f000 f802 bl 8000010 <xmain>
800000c: e7fe b.n 800000c <reset+0x4>
...
08000010 <notmain>:
8000010: 2000 movs r0,#0
8000012: 4770 bx lr
我尝试查看我的文件中的工具链以找到与链接器脚本有关的 main 的任何其他参考,并在此过程中获得了一些其他帮助,但似乎没有明确的解决方案来解释为什么会这样。当然,如果您创建自己的链接器或生成的链接器,您就不会遇到这个问题,但我只是好奇,因为我正在尝试更多地学习该工具。
解决方法
..但我只是好奇,因为我正在尝试更多地学习该工具
arm-eabi-none 旨在与 newlib 一起使用(作为猜测,因为您没有另外说明)。这可以处理elf 格式的文件,它是一个“库”,但没有操作系统。如果 newlib 机制希望 main()
成为第一个,该工具将设置如下。您不需要 elf 文件,而是二进制文件。如果您想要二进制文件(ihex、srec 等),请使用链接描述文件!这就是它的意义所在。
使用 ld --verbose
查看默认链接器脚本。您在抱怨发出的 .text
的顺序,但您没有做任何事情来定义排序。链接描述文件可能需要 main
为第一个,以便其他一些库功能可以工作。您有一个重置向量和一个 CPU,用于初始化堆栈和“重置向量”或初始代码。
这仍然在“坏情况”中发出,但没有正确放置。您需要有一个自定义链接器脚本,并将其定位为二进制文件中的第一件事。依靠链接器正确放置它很容易出错。工具的升级绝对可以改变顺序。
请参阅:Can _start be a thumb function,您是否有-nostartfiles -static -nostdlib
之类的选项并使用自定义链接器脚本作为 elf 二进制文件不太可能被理解,您需要闪烁/将二进制文件刻录到任何要读取复位向量的引导设备(或内置 CPU)。