Gcc 裸机ARM链接器脚本:如何将初始化数据从ROM重新定位到RAM?
我想把全局变量的初始值放在ROM部分,然后重新定位它们的地址并将它们的值复制到RAM中(这样程序就可以编辑) 我的链接器脚本部分:Gcc 裸机ARM链接器脚本:如何将初始化数据从ROM重新定位到RAM?,gcc,linker,arm,gnu,linker-scripts,Gcc,Linker,Arm,Gnu,Linker Scripts,我想把全局变量的初始值放在ROM部分,然后重新定位它们的地址并将它们的值复制到RAM中(这样程序就可以编辑) 我的链接器脚本部分: /* code */ .text : { __text_start = .; *(.text) __text_end = .; } > ROM /* Initialized global and static variables */ .data : AT ( __text_end ) { __data_start =
/* code */
.text :
{
__text_start = .;
*(.text)
__text_end = .;
} > ROM
/* Initialized global and static variables */
.data : AT ( __text_end )
{
__data_start = . ;
*(.data);
__data_end = . ;
} > RAM
int global_var = 0xAAA;
void main()
{
global_var = 0xBBB;
}
我的启动ROM代码:
/* code */
.text :
{
__text_start = .;
*(.text)
__text_end = .;
} > ROM
/* Initialized global and static variables */
.data : AT ( __text_end )
{
__data_start = . ;
*(.data);
__data_end = . ;
} > RAM
int global_var = 0xAAA;
void main()
{
global_var = 0xBBB;
}
问题:初始值0xAAA
位于编译的bin文件中的RAM
地址,而不是ROM
如何在ROM中定义初始数据值,然后将其地址重新定位到RAM
感谢您的帮助看看关于内存布局和链接的全面说明
您必须添加相关的启动代码,通过ROM中的RAM部分复制到RAM中的目的地,并初始化C运行时环境(zeroning.bss等)。网络中有大量的示例,通常由SDK提供,与同样提供的链接器脚本相匹配,因为这些文件必须匹配
int global_var = 0xAAA;
int global_too;
void main()
{
global_var = 0xBBB;
}
MEMORY
{
bob : ORIGIN = 0x08000000, LENGTH = 0x100
ted : ORIGIN = 0x20000000, LENGTH = 0x100
}
SECTIONS
{
.text : { *(.text*) } > bob
.rodata : { *(.rodata*) } > bob
.data : { *(.data*) } > ted AT > bob
.bss : { *(.bss*) } > ted AT > bob
}
Disassembly of section .text:
08000000 <reset-0x8>:
8000000: 20000400
8000004: 08000009
08000008 <reset>:
8000008: f000 f802 bl 8000010 <main>
800000c: e7fe b.n 800000c <reset+0x4>
...
08000010 <main>:
8000010: 4b01 ldr r3, [pc, #4] ; (8000018 <main+0x8>)
8000012: 4a02 ldr r2, [pc, #8] ; (800001c <main+0xc>)
8000014: 601a str r2, [r3, #0]
8000016: 4770 bx lr
8000018: 20000000
800001c: 00000bbb
Disassembly of section .data:
20000000 <global_var>:
20000000: 00000aaa
Disassembly of section .bss:
20000004 <global_too>:
20000004: 00000000
在引导过程中进行双重检查
.align
.word __data_rom_start__
.word __data_start__
.word __data_end__
.word __bss_start__
.word __bss_end__
Disassembly of section .text:
08000000 <reset-0x8>:
8000000: 20000400
8000004: 08000009
08000008 <reset>:
8000008: f000 f80c bl 8000024 <main>
800000c: e7fe b.n 800000c <reset+0x4>
800000e: 46c0 nop ; (mov r8, r8)
8000010: 08000034
8000014: 20000000
8000018: 20000004
800001c: 20000004
8000020: 20000008
08000024 <main>:
8000024: 4b01 ldr r3, [pc, #4] ; (800002c <main+0x8>)
8000026: 4a02 ldr r2, [pc, #8] ; (8000030 <main+0xc>)
8000028: 601a str r2, [r3, #0]
800002a: 4770 bx lr
800002c: 20000000
8000030: 00000bbb
Disassembly of section .data:
20000000 <global_var>:
20000000: 00000aaa
Disassembly of section .bss:
20000004 <global_too>:
20000004: 00000000
8000010: 08000034
8000014: 20000000
8000018: 20000004
800001c: 20000004
8000020: 20000008
arm-none-eabi-nm so.elf
20000008 B __bss_end__
20000004 B __bss_start__
20000004 D __data_end__
08000034 T __data_rom_start__
20000000 D __data_start__
20000004 B global_too
20000000 D global_var
08000024 T main
08000008 t reset
hexdump -C so.bin
00000000 00 04 00 20 09 00 00 08 00 f0 0c f8 fe e7 c0 46 |... ...........F|
00000010 34 00 00 08 00 00 00 20 04 00 00 20 04 00 00 20 |4...... ... ... |
00000020 08 00 00 20 01 4b 02 4a 1a 60 70 47 00 00 00 20 |... .K.J.`pG... |
00000030 bb 0b 00 00 aa 0a 00 00 |........|
00000038
YMMV
幸运或不幸的是,GNULD提供了不止一种方法来解决这个问题,正如您已经开始用链接器脚本演示的那样。同时,GNULD使它成为解决这个问题的一个PITA,它对放置某物的位置/方式非常敏感。;您将看到各种不同的示例,但它们似乎都有效
还请注意,这些名称也不重要:
MEMORY
{
bob : ORIGIN = 0x08000000, LENGTH = 0x100
ted : ORIGIN = 0x20000000, LENGTH = 0x100
}
SECTIONS
{
.hello : { *(.text*) } > bob
.world : { *(.data*) } > ted AT > bob
}
Disassembly of section .hello:
08000000 <reset-0x8>:
8000000: 20000400
8000004: 08000009
08000008 <reset>:
8000008: f000 f802 bl 8000010 <main>
800000c: e7fe b.n 800000c <reset+0x4>
...
08000010 <main>:
8000010: 4b01 ldr r3, [pc, #4] ; (8000018 <main+0x8>)
8000012: 4a02 ldr r2, [pc, #8] ; (800001c <main+0xc>)
8000014: 601a str r2, [r3, #0]
8000016: 4770 bx lr
8000018: 20000000
800001c: 00000bbb
Disassembly of section .world:
20000000 <global_var>:
20000000: 00000aaa
hexdump -C so.bin
00000000 00 04 00 20 09 00 00 08 00 f0 02 f8 fe e7 00 00 |... ............|
00000010 01 4b 02 4a 1a 60 70 47 00 00 00 20 bb 0b 00 00 |.K.J.`pG... ....|
00000020 aa 0a 00 00 |....|
00000024
嗨,我有一个从ROM到RAM复制数据的启动代码。。我的问题是,链接器脚本没有将初始数据放在ROM中(而是放在它应该重新定位到的RAM区域),我不明白为什么以及我在链接器脚本中写错了什么好。然后阅读链接的文章,它很好地解释了这一点,并提供了一些例子。
} > RAM AT > ROM