杰发科技AC7840——编译链接过程

链接脚本(.ld)与启动文件(.s)的关系

概述

在嵌入式 ARM 项目中,链接脚本(.ld)和启动汇编文件(.s)通过符号名在链接阶段建立联系。启动文件引用符号,链接脚本定义符号地址。


1. 启动文件定义符号引用

启动文件 startup_ac7840x.s 中引用了链接脚本定义的符号:

asm 复制代码
; 第 46-54 行,定义数据段和 BSS 段的地址引用
.word  _sidata    ; Flash 中 .data 初始值地址
.word  _sdata     ; RAM 中 .data 段起始地址
.word  _edata     ; RAM 中 .data 段结束地址
.word  _sbss      ; .bss 段起始地址
.word  _ebss      ; .bss 段结束地址

; 第 71 行,设置栈指针
ldr   sp, =_estack   ; 栈顶地址

2. 链接脚本定义这些符号

链接脚本 ac7840x_flash.ld 中定义了上述符号的具体地址:

ld 复制代码
_sidata = .;              /* 第 83 行,Flash 中 .data 初始值地址 */
_sdata = .;               /* 第 94 行,RAM 中 .data 段起始 */
_edata = .;               /* 第 99 行,RAM 中 .data 段结束 */
_sbss = .;                /* 第 124 行,.bss 段起始 */
_ebss = .;                /* 第 131 行,.bss 段结束 */
_estack = .;              /* 第 159 行,栈顶地址 */

3. 链接阶段整合

编译和链接的流程:

复制代码
汇编编译:  startup_ac7840x.s  →  startup_ac7840x.o  (符号未解析)
C 编译:    main.c            →  main.o
链接:      gcc *.o -T ac7840x_flash.ld  →  Demo.elf
                ↓
        链接器用 .ld 中定义的地址
        替换 .o 中的符号引用

在链接阶段,链接器读取链接脚本,确定各符号的最终地址,然后替换目标文件(.o)中所有对这些符号的引用。


4. 实际作用

启动文件 Reset_Handler 使用链接脚本定义的符号完成系统初始化:

asm 复制代码
ldr  r3, =_sidata    ; 从 Flash 读取 .data 初始值
ldr  r0, =_sdata     ; .data 在 RAM 中的起始地址
ldr  r3, =_edata     ; .data 在 RAM 中的结束地址
ldr  r2, =_sbss      ; .bss 起始地址
ldr  r3, =_ebss      ; .bss 结束地址

初始化过程:

  1. .data 段初始值从 Flash 拷贝到 RAM
  2. .bss 段清零
  3. 设置栈指针 sp = _estack
  4. 调用 SystemInit 进行时钟初始化
  5. 调用 main 进入应用程序

5. 内存布局示例

复制代码
Flash (0x00000000):
  ┌─────────────────┐
  │  .isr_vector     │  ← 中断向量表
  ├─────────────────┤
  │  .text           │  ← 程序代码
  ├─────────────────┤
  │  .data 初始值    │  ← _sidata 指向此处
  └─────────────────┘

RAM (0x1FFF0000):
  ┌─────────────────┐
  │  .data           │  ← _sdata ~ _edata
  ├─────────────────┤
  │  .bss            │  ← _sbss ~ _ebss
  ├─────────────────┤
  │  .heap           │  ← 堆区
  ├─────────────────┤
  │  .stack          │  ← _estack 指向栈顶
  └─────────────────┘

总结

  • 启动文件(.s):定义处理器复位后执行的初始化代码,引用链接脚本中的符号
  • 链接脚本(.ld):定义各段在内存中的位置,提供符号的具体地址
  • 联系 :两者通过符号名在链接阶段建立联系,完成系统的内存初始化
相关推荐
学嵌入式的小杨同学3 天前
STM32 进阶封神之路(三十):IIC 通信深度实战 —— 软件模拟 IIC + 光照传感器(BH1750)全解析(底层时序 + 代码落地)
stm32·单片机·嵌入式硬件·mcu·硬件架构·硬件工程·智能硬件
光子物联单片机3 天前
STM32传感器模块编程实践(十九) 光子物联北斗GPS定位模块简介及驱动源码
stm32·单片机·嵌入式硬件·mcu
李永奉3 天前
杰理芯片SDK-更改芯片产品蓝牙名功能
单片机·嵌入式硬件·mcu·物联网·语音识别
乐鑫科技 Espressif3 天前
乐鑫发布 ESP32-S31:高性能多协议双核 RISC-V,面向 AI 智能交互
人工智能·mcu·esp32·乐鑫科技
电子科技圈3 天前
芯科科技闪耀2026嵌入式世界展以Connected Intelligence赋能,构建边缘智能网联新生态
人工智能·嵌入式硬件·mcu·物联网·智慧城市·健康医疗·智能硬件
学嵌入式的小杨同学5 天前
STM32 进阶封神之路(二十七):MQTT 深度解析 —— 从协议原理到 OneNET 云平台接入(底层逻辑 + AT 指令开发)
stm32·单片机·嵌入式硬件·mcu·硬件架构·pcb·嵌入式实时数据库
学嵌入式的小杨同学6 天前
STM32 进阶封神之路(二十五):ESP8266 深度解析 —— 从 WiFi 通信原理到 AT 指令开发(底层逻辑 + 实战基础)
c++·vscode·stm32·单片机·嵌入式硬件·mcu·智能硬件
学嵌入式的小杨同学6 天前
STM32 进阶封神之路(二十六):ESP8266 实战全攻略 ——TCP 通信 + 数据上传 + 远程控制 + 透传模式(库函数 + 代码落地)
stm32·单片机·嵌入式硬件·mcu·硬件架构·硬件工程·智能硬件
小白橘颂7 天前
【C语言】基础概念梳理(一)
c语言·开发语言·stm32·单片机·mcu·物联网·51单片机