编译与链接的本质:段(Section)的生成与定位

1. 编译阶段:分类与生成

  • 输入:源代码(C/C++/汇编等)
  • 处理 :编译器根据变量/函数的属性(是否初始化、是否用 __attribute__((section("name"))) 修饰等)将内容归类到不同的段(Section)。
  • 输出 :目标文件(.o.obj),其中每个段内仅包含相对于该段起始的偏移地址最终运行时地址尚未确定

2. 链接阶段:定位与整合

  • 输入 :多个目标文件 + 链接脚本.ld
  • 处理
    1. 收集所有目标文件中的同名段,合并成一个大的段。
    2. 按照链接脚本的规则,为每个段分配最终的运行时地址 (在裸机/固件环境下即物理地址)。
    3. 修正代码中的地址引用(重定位),生成可执行映像。
  • 输出 :可执行映像文件(如 .elf.bin.hex

3. 自定义段的工作机制

  • 在代码中定义 :使用编译器扩展(如 GCC 的 __attribute__((section("my_section"))))将特定变量或函数放入自定义段。

  • 在链接脚本中声明:必须显式描述如何处理该自定义段,例如:

    my_section : { *(.my_section) } > RAM

否则,该段会被链接器丢弃,不会出现在最终内存映像中。

4. 核心总结

编译负责"分类",链接负责"定位"

链接脚本是连接编译输出与最终内存布局的蓝图

自定义段通过编译属性生成,再通过链接脚本精确落地到特定内存地址,这是固件开发中实现精细内存控制(如调试缓冲、DMA 区域、保留内存)的根本方法。


注:上述机制适用于裸机/固件环境(无操作系统加载器介入)。在有操作系统的环境中,链接脚本生成的为相对地址,最终由操作系统加载器完成虚拟地址映射。

相关推荐
做个文艺程序员2 小时前
第04篇:K8s 弹性伸缩实战:HPA、VPA、KEDA——Java SaaS 应对流量洪峰的秘密武器
java·容器·kubernetes·弹性伸缩·自动扩容·ai 推理伸缩
石山代码6 小时前
ArrayList / HashMap / ConcurrentHashMap
java·开发语言
9分钟带帽6 小时前
linux_系统开机自动执行shell脚本
linux·服务器
程序大视界6 小时前
【Python系列课程】Python正则表达式(下):环视、命名分组与日志实战
开发语言·python·正则表达式
枫叶v.7 小时前
Agent 分层存储架构设计:从记忆方法到中间件选型
开发语言·python
AskHarries7 小时前
系统提示词、开发者指令和用户输入的优先级
java·前端·数据库
daidaidaiyu8 小时前
ThingsBoard 规则链系统源码分析和自定义定时器
java
嵌入式小能手8 小时前
飞凌嵌入式ElfBoard-进程间的通信之命名管道
linux·服务器·算法
sleven fung8 小时前
MinerU与BabelDOC与KTransformers与OpenAI API库
开发语言·python·ai·langchain
小毛驴8508 小时前
spring-boot-maven-plugin,maven-compiler-plugin 功能对比
java·python·maven