如何在GNU LD中实现自定义输出段?编写脚本后遇分配难题
如何将代码/数据分配到自定义链接段
嘿,你已经在LD脚本里搞定了最核心的内存区域和输出段定义,剩下的就是给要放到这个自定义段的代码/变量做个标记,让链接器能精准找到它们~下面分场景给你具体操作方法:
1. C/C++代码的标记方式
单个函数/变量的标记
在目标函数或全局变量的定义前,加上GCC的段属性扩展,直接指定要放入的段:
// 标记函数到自定义段 __attribute__((section(".my_custom_section"))) void my_custom_func(void) { // 你的函数逻辑 } // 标记全局变量到自定义段 __attribute__((section(".my_custom_section"))) uint32_t my_custom_data = 0x12345678;
批量标记的小技巧
如果有一堆函数/变量要放到这个段,建议定义一个复用宏,避免重复写属性:
#define PUT_IN_CUSTOM_SECTION __attribute__((section(".my_custom_section"))) PUT_IN_CUSTOM_SECTION void func_a(void); PUT_IN_CUSTOM_SECTION void func_b(void); PUT_IN_CUSTOM_SECTION uint8_t buffer[64]; PUT_IN_CUSTOM_SECTION uint16_t config_val;
2. 汇编代码的标记方式
如果是手写汇编,直接在符号定义前用.section指令指定目标段,注意属性要和LD脚本里的RW对应:
.section .my_custom_section, "rw" ; "rw"对应LD脚本里的可读可写属性 .global my_asm_routine my_asm_routine: ; 你的汇编指令 bx lr
3. 验证配置是否生效
链接完成后,用objdump工具检查符号地址,确认它们落在你指定的0x00002400 ~ 0x00002800区间内:
objdump -t your_application.elf | grep my_custom_
如果输出的地址符合预期,就说明整个配置成功啦~
额外注意事项
- 你LD脚本里的
KEEP(*(.my_custom_section))很关键,它能防止链接器把未被直接引用的符号(比如中断服务函数)优化掉,要是你的自定义段里有这类代码,这个配置绝对不能少。 - 段属性要保持一致:如果自定义段是放只读代码的,记得把LD脚本里的
RW改成RX,同时汇编里的属性也要改成"rx"。
内容的提问来源于stack exchange,提问作者Jim Fell
相关产品推荐
相关产品推荐

