向量.s
.cpu cortex-m3
.thumb
.word 0x20008000 /* stack top address */
.word _start /* Reset */
.word hang
.word hang
/* ... */
.thumb_func
hang: b .
.thumb_func
.globl _start
_start:
bl notmain
b hang
不是main.c
extern void fun ( unsigned int );
void notmain ( void )
{
fun(7);
}
乐趣.c
void fun ( unsigned int x )
{
}
生成文件
hello.elf : vectors.s fun.c notmain.c memmap
arm-none-eabi-as vectors.s -o vectors.o
arm-none-eabi-gcc -Wall -O2 -nostdlib -nostartfiles -ffreestanding -mthumb -mcpu=cortex-m3 -march=armv7-m -c notmain.c -o notmain.o
arm-none-eabi-gcc -Wall -O2 -nostdlib -nostartfiles -ffreestanding -mthumb -mcpu=cortex-m3 -march=armv7-m -c fun.c -o fun.o
arm-none-eabi-ld -o hello.elf -T memmap vectors.o notmain.o fun.o
arm-none-eabi-objdump -D hello.elf > hello.list
arm-none-eabi-objcopy hello.elf -O binary hello.bin
因此,如果链接器脚本(memmap 是我使用的名称)看起来像这样
MEMORY
{
rom : ORIGIN = 0x00000000, LENGTH = 0x40000
ram : ORIGIN = 0x20000000, LENGTH = 0x8000
}
SECTIONS
{
.text : { *(.text*) } > rom
.bss : { *(.bss*) } > ram
}
由于上述所有内容都是 .text,没有 .bss 或 .data,因此链接器采用 ld 命令行上列出的对象并将它们从该地址开始放置...
.text 部分的mbly:
00000000 <hang-0x10>:
0: 20008000 andcs r8, r0, r0
4: 00000013 andeq r0, r0, r3, lsl r0
8: 00000011 andeq r0, r0, r1, lsl r0
c: 00000011 andeq r0, r0, r1, lsl r0
00000010 <hang>:
10: e7fe b.n 10 <hang>
00000012 <_start>:
12: f000 f801 bl 18 <notmain>
16: e7fb b.n 10 <hang>
00000018 <notmain>:
18: 2007 movs r0, #7
1a: f000 b801 b.w 20 <fun>
1e: bf00 nop
00000020 <fun>:
20: 4770 bx lr
22: bf00 nop
因此,要使其正常工作,您必须小心地将引导代码放在命令行的首位。但是您也可以使用链接描述文件来执行此类操作。
顺序似乎很重要,首先列出特定的目标文件,然后是通用的 .text
MEMORY
{
romx : ORIGIN = 0x00000000, LENGTH = 0x1000
romy : ORIGIN = 0x00010000, LENGTH = 0x1000
ram : ORIGIN = 0x00030000, LENGTH = 0x1000
bob : ORIGIN = 0x00040000, LENGTH = 0x1000
ted : ORIGIN = 0x00050000, LENGTH = 0x1000
}
SECTIONS
{
abc : { vectors.o } > romx
def : { fun.o } > ted
.text : { *(.text*) } > romy
.bss : { *(.bss*) } > ram
}
我们得到了这个
00000000 <hang-0x10>:
0: 20008000 andcs r8, r0, r0
4: 00000013 andeq r0, r0, r3, lsl r0
8: 00000011 andeq r0, r0, r1, lsl r0
c: 00000011 andeq r0, r0, r1, lsl r0
00000010 <hang>:
10: e7fe b.n 10 <hang>
00000012 <_start>:
12: f00f fff5 bl 10000 <notmain>
16: e7fb b.n 10 <hang>
Disassembly of section def:
00050000 <fun>:
50000: 4770 bx lr
50002: bf00 nop
Disassembly of section .text:
00010000 <notmain>:
10000: 2007 movs r0, #7
10002: f03f bffd b.w 50000 <fun>
10006: bf00 nop
简短的回答是使用 gnu 工具,您使用链接器脚本来操纵事情的最终结果,我假设您希望这些函数位于某个指定位置的 rom 中。我不太明白你在做什么。但是,例如,如果您尝试将一些简单的东西,例如最初在闪存中的 main() 分支,而 main() 在闪存中更深,然后以某种方式通过闪存中更深的任何代码或通过其他方法,然后后来你只擦除和重新编程接近零的东西。你仍然需要一个简单的分支到 main() 第一次。您可以强制我所说的vectors.o位于地址零,然后.text可以在闪存中更深,将代码的所有重置基本上放在那里,然后将其留在闪存中并仅替换零处的东西。
像这样
MEMORY
{
romx : ORIGIN = 0x00000000, LENGTH = 0x1000
romy : ORIGIN = 0x00010000, LENGTH = 0x1000
ram : ORIGIN = 0x00030000, LENGTH = 0x1000
bob : ORIGIN = 0x00040000, LENGTH = 0x1000
ted : ORIGIN = 0x00050000, LENGTH = 0x1000
}
SECTIONS
{
abc : { vectors.o } > romx
.text : { *(.text*) } > romy
.bss : { *(.bss*) } > ram
}
给予
00000000 <hang-0x10>:
0: 20008000 andcs r8, r0, r0
4: 00000013 andeq r0, r0, r3, lsl r0
8: 00000011 andeq r0, r0, r1, lsl r0
c: 00000011 andeq r0, r0, r1, lsl r0
00000010 <hang>:
10: e7fe b.n 10 <hang>
00000012 <_start>:
12: f00f fff7 bl 10004 <notmain>
16: e7fb b.n 10 <hang>
Disassembly of section .text:
00010000 <fun>:
10000: 4770 bx lr
10002: bf00 nop
00010004 <notmain>:
10004: 2007 movs r0, #7
10006: f7ff bffb b.w 10000 <fun>
1000a: bf00 nop
然后留下 0x10000 的东西并稍后替换 0x00000 的东西。
无论如何,简短的回答是链接描述文件你需要制作一个链接描述文件来把东西放在你想要的地方。gnu 链接器脚本可能会变得非常复杂,我倾向于简单。
如果你想把所有东西都放在其他地址,包括你的向量表,那么可能是这样的:
酒花
.cpu cortex-m3
.thumb
.word 0x20008000 /* stack top address */
.word _start /* Reset */
.word hang
.word hang
/* ... */
.thumb_func
hang: b .
.thumb_func
ldr r0,=_start
bx r0
和这个
MEMORY
{
romx : ORIGIN = 0x00000000, LENGTH = 0x1000
romy : ORIGIN = 0x00010000, LENGTH = 0x1000
ram : ORIGIN = 0x00030000, LENGTH = 0x1000
bob : ORIGIN = 0x00040000, LENGTH = 0x1000
ted : ORIGIN = 0x00050000, LENGTH = 0x1000
}
SECTIONS
{
abc : { hop.o } > romx
.text : { *(.text*) } > romy
.bss : { *(.bss*) } > ram
}
给了这个
Disassembly of section abc:
00000000 <hang-0x10>:
0: 20008000 andcs r8, r0, r0
4: 00010013 andeq r0, r1, r3, lsl r0
8: 00000011 andeq r0, r0, r1, lsl r0
c: 00000011 andeq r0, r0, r1, lsl r0
00000010 <hang>:
10: e7fe b.n 10 <hang>
12: 4801 ldr r0, [pc, #4] ; (18 <hang+0x8>)
14: 4700 bx r0
16: 00130000
1a: 20410001
Disassembly of section .text:
00010000 <hang-0x10>:
10000: 20008000 andcs r8, r0, r0
10004: 00010013 andeq r0, r1, r3, lsl r0
10008: 00010011 andeq r0, r1, r1, lsl r0
1000c: 00010011 andeq r0, r1, r1, lsl r0
00010010 <hang>:
10010: e7fe b.n 10010 <hang>
00010012 <_start>:
10012: f000 f803 bl 1001c <notmain>
10016: e7fb b.n 10010 <hang>
00010018 <fun>:
10018: 4770 bx lr
1001a: bf00 nop
0001001c <notmain>:
1001c: 2007 movs r0, #7
1001e: f7ff bffb b.w 10018 <fun>
10022: bf00 nop
然后您可以将向量表更改为例如 0x10000。
如果您要问一个不同的问题,例如引导加载程序位于 0x00000,那么引导加载程序会修改闪存以添加应用程序,例如在 0x20000,然后您想运行该应用程序,有一些更简单的解决方案不一定需要您修改向量表。