链接器:将除两个函数之外的所有函数移动到特定内存区域
Linker: Moving all functions but two to a specific memory region
我正在为 PIC32MX 微控制器开发固件。程序内存应该分成三段:
- 第 1 节:中断服务程序和主要函数 (
startup_region
)
- 第 2 部分:剩余程序内存的 50% (
program1
)
- 第 3 部分:剩余程序内存的 50% (
program2
)
固件只保存在Section 2 或Section 3 中,另一个是为将来更新保留的。因此,活动区域可以安全地覆盖其他区域以存储更新。配置位被翻转,第 0 节的 main() 函数现在在重新启动时跳转到另一个程序。
因此,我需要链接器将除 isr
和 main
之外的所有函数放入第 1 节,将其他所有函数放入第 2 节。第 3 节必须完全留空,因为它可能会被覆盖将来。
我已经尝试通过修改默认链接描述文件来实现这一点,但是没有成功。
linkerscript.ld:
/* [...] */
INCLUDE procdefs.gld
/* [...] */
SECTIONS
{
/* [...] */
.text :
{
/* isr() and main() should be at the very first locations in program memory */
*(.text.isr)
*(.text.main)
/* [...] */
. = ALIGN(4) ;
} >kseg0_program_mem
.program1 :
{
*(*.text)
} >program1
/* [...] */
}
procdefs.gld:
/* [...] */
MEMORY
{
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x10000
startup_region (rx) : ORIGIN = 0x9D000000, LENGTH = 0x01000
program1 (rx) : ORIGIN = 0x9D002000, LENGTH = 0x07000
program2 (rx) : ORIGIN = 0x9D009000, LENGTH = 0x07000
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
/* [...] */
}
/* [...] */
结果如下:
isr()
和main()
是它们应该在的位置(0x9D00000
是程序flash开始的KSEG0
虚拟地址)
.text 0x9d000000 0x94
*(.text.isr)
.text.isr 0x9d000000 0x60 build/default/production/main.o
0x9d000000 isr
*(.text.main)
.text.main 0x9d000060 0x34 build/default/production/main.o
0x9d000060 main
正确放置了 program1
区域并且正确列出了大多数目标文件(但是请注意,再次列出了 main.o
-- 它已被使用)。
.program1 0x9d002000 0xc44
*(*.text)
.text 0x9d002000 0x0 /opt/microchip/xc32/v2.10/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/./proc/32MX330F064H/crt0_mips32r2.o
.text 0x9d002000 0x0 /opt/microchip/xc32/v2.10/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/debug-exception-return.o
.text 0x9d002000 0x0 build/default/production/main.o
.text 0x9d002000 0x0 build/default/production/commands.o
/* [...] */
.text 0x9d002000 0x0 build/default/production/micro-ecc/uECC.o
但是,某些功能位于该区域之外:
.text.uECC_verify
0x9d000b04 0x7c0
.text.uECC_verify
0x9d000b04 0x7c0 build/default/production/micro-ecc/uECC.o
0x9d000b04 uECC_verify
.text.vli_mmod_fast_secp256r1
0x9d0012c4 0x520
.text.vli_mmod_fast_secp256r1
0x9d0012c4 0x520 build/default/production/micro-ecc/uECC.o
我不明白为什么会这样。
我的问题是:
- 如何强制链接器将所有函数(
main
和 isr
除外)放入 program1
.
- 如何禁止链接器将任何内容放入
program2
,以使其保持空闲状态。
我正在用 -ffunction-segments
开关编译软件,这样每个函数都有自己的段。
原始链接描述文件还包含这个看起来可疑的评论:
/* Code Sections - Note that input sections *(.text) and *(.text.*)
are not mapped here. Starting in C32 v2.00, the best-fit allocator
locates them, so that .text may flow around absolute sections
as needed.
*/
目标文件main.o与函数的内存段.tex.main
不一样。如果这个目标文件产生一些其他文本段,它们将被放置在别处。这就是您在地图文件中看到的内容。
正如@Ctx 提到的,您的文本段的语法是错误的,而不是 *(*.text)
,应该是
.program1 :
{
*(.text*)
} >program1
这样所有其他文本段都会正确地放置在 program1
内存中。
我正在为 PIC32MX 微控制器开发固件。程序内存应该分成三段:
- 第 1 节:中断服务程序和主要函数 (
startup_region
) - 第 2 部分:剩余程序内存的 50% (
program1
) - 第 3 部分:剩余程序内存的 50% (
program2
)
固件只保存在Section 2 或Section 3 中,另一个是为将来更新保留的。因此,活动区域可以安全地覆盖其他区域以存储更新。配置位被翻转,第 0 节的 main() 函数现在在重新启动时跳转到另一个程序。
因此,我需要链接器将除 isr
和 main
之外的所有函数放入第 1 节,将其他所有函数放入第 2 节。第 3 节必须完全留空,因为它可能会被覆盖将来。
我已经尝试通过修改默认链接描述文件来实现这一点,但是没有成功。
linkerscript.ld:
/* [...] */
INCLUDE procdefs.gld
/* [...] */
SECTIONS
{
/* [...] */
.text :
{
/* isr() and main() should be at the very first locations in program memory */
*(.text.isr)
*(.text.main)
/* [...] */
. = ALIGN(4) ;
} >kseg0_program_mem
.program1 :
{
*(*.text)
} >program1
/* [...] */
}
procdefs.gld:
/* [...] */
MEMORY
{
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x10000
startup_region (rx) : ORIGIN = 0x9D000000, LENGTH = 0x01000
program1 (rx) : ORIGIN = 0x9D002000, LENGTH = 0x07000
program2 (rx) : ORIGIN = 0x9D009000, LENGTH = 0x07000
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
/* [...] */
}
/* [...] */
结果如下:
isr()
和main()
是它们应该在的位置(0x9D00000
是程序flash开始的KSEG0
虚拟地址)
.text 0x9d000000 0x94
*(.text.isr)
.text.isr 0x9d000000 0x60 build/default/production/main.o
0x9d000000 isr
*(.text.main)
.text.main 0x9d000060 0x34 build/default/production/main.o
0x9d000060 main
正确放置了 program1
区域并且正确列出了大多数目标文件(但是请注意,再次列出了 main.o
-- 它已被使用)。
.program1 0x9d002000 0xc44
*(*.text)
.text 0x9d002000 0x0 /opt/microchip/xc32/v2.10/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/./proc/32MX330F064H/crt0_mips32r2.o
.text 0x9d002000 0x0 /opt/microchip/xc32/v2.10/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/debug-exception-return.o
.text 0x9d002000 0x0 build/default/production/main.o
.text 0x9d002000 0x0 build/default/production/commands.o
/* [...] */
.text 0x9d002000 0x0 build/default/production/micro-ecc/uECC.o
但是,某些功能位于该区域之外:
.text.uECC_verify
0x9d000b04 0x7c0
.text.uECC_verify
0x9d000b04 0x7c0 build/default/production/micro-ecc/uECC.o
0x9d000b04 uECC_verify
.text.vli_mmod_fast_secp256r1
0x9d0012c4 0x520
.text.vli_mmod_fast_secp256r1
0x9d0012c4 0x520 build/default/production/micro-ecc/uECC.o
我不明白为什么会这样。
我的问题是:
- 如何强制链接器将所有函数(
main
和isr
除外)放入program1
. - 如何禁止链接器将任何内容放入
program2
,以使其保持空闲状态。
我正在用 -ffunction-segments
开关编译软件,这样每个函数都有自己的段。
原始链接描述文件还包含这个看起来可疑的评论:
/* Code Sections - Note that input sections *(.text) and *(.text.*)
are not mapped here. Starting in C32 v2.00, the best-fit allocator
locates them, so that .text may flow around absolute sections
as needed.
*/
目标文件main.o与函数的内存段.tex.main
不一样。如果这个目标文件产生一些其他文本段,它们将被放置在别处。这就是您在地图文件中看到的内容。
正如@Ctx 提到的,您的文本段的语法是错误的,而不是 *(*.text)
,应该是
.program1 :
{
*(.text*)
} >program1
这样所有其他文本段都会正确地放置在 program1
内存中。