You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nordic nRF Connect SDK链接脚本疑问:__ramfunc_size未定义却生效?

链接脚本中提前引用__ramfunc_size却正常工作的解惑

问题背景与疑问

MPU所用内存段需满足两个要求:

  • 段起始地址必须与段大小对齐
  • 段大小必须是2的幂(如32、64、1024等)

以下代码取自Nordic_nRF_Connect_SDK\v2.4.2\zephyr\arch\common\ramfunc.ld,经测试可成功实现符合MPU要求的对齐,但存在疑问:在.ramfunc段定义中,前后两次调用MPU_ALIGN(__ramfunc_size)时,__ramfunc_size是在段定义外后续才通过__ramfunc_end - __ramfunc_start计算得到的。若按链接脚本逐行顺序解析的认知,此时__ramfunc_size应为0,但实际项目中代码却能正常工作,恳请解惑。

相关代码

#define MPU_ALIGN(region_size) \
    . = ALIGN(_region_min_align); \
    . = ALIGN( 1 << LOG2CEIL(region_size))
SECTION_DATA_PROLOGUE(.ramfunc,,)
{
    MPU_ALIGN(__ramfunc_size);
    __ramfunc_start = .;
    *(.ramfunc)
    *(".ramfunc.*")
    MPU_ALIGN(__ramfunc_size);
    __ramfunc_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
__ramfunc_size = __ramfunc_end - __ramfunc_start;

解惑

链接器处理链接脚本并非单次逐行顺序执行,而是分多阶段完成整个链接过程,这是核心原因:

  1. 第一阶段:收集段内容与初步计算
    链接器首先扫描所有输入目标文件,收集.ramfunc及其子段的所有内容,先确定__ramfunc_start和__ramfunc_end的初始位置(此时还未执行MPU对齐调整),并计算出__ramfunc_size的初步非零值。
  2. 第二阶段:基于实际大小完成对齐调整
    拿到第一阶段得到的真实__ramfunc_size后,链接器会重新处理.ramfunc段中的MPU_ALIGN指令:
    • 先调整段起始地址,使其与__ramfunc_size对齐,同时满足最小对齐要求_region_min_align
    • 放置完.ramfunc段内容后,再调整段结束地址,确保最终的段大小是2的幂,且结束地址也符合对齐要求
  3. 最终更新
    完成对齐调整后,链接器会更新__ramfunc_end的最终值,并重新计算出符合MPU要求的__ramfunc_size。

简单来说,链接器会先“预估”出.ramfunc段的实际大小,再用这个大小去做对齐调整,最后确定最终的段地址和大小,而非严格按脚本的书写顺序单次执行。

内容的提问来源于stack exchange,提问作者pasu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 21:12:16