杰发科技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):定义各段在内存中的位置,提供符号的具体地址
  • 联系 :两者通过符号名在链接阶段建立联系,完成系统的内存初始化
相关推荐
芯片设计-曾工33 分钟前
YL1621(SSOP28)国产段码LCD驱动芯片|PIN‑PIN兼容HT1621,储能电量显示板CH2505B国产化替换方案
stm32·单片机·嵌入式硬件·mcu·硬件工程
DevHub1 天前
STM32 USB HID 教程:TinyUSB 实现键盘设备,从描述符到枚举
arm开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
etc95272 天前
keil下如何指定stack和heap地址
ide·mcu
DevHub2 天前
probe-rs 教程:一行命令替代 OpenOCD 烧写调试 Cortex-M
arm开发·嵌入式硬件·mcu·rust
etc95272 天前
IAR下如何同时指定section的LMA和VMA
arm开发·嵌入式硬件·mcu
花月mmc2 天前
Arduino UNO R4 ——电压电流数据显示
嵌入式硬件·mcu·物联网
笨笨饿3 天前
#109_BK7258 蓝牙 A2DP 音频数据通路深度解析
python·stm32·单片机·mcu·物联网·编辑器·音视频
国产HT1621B3 天前
外挂 YL1621 SSOP48 芯片 vs MCU 内置 LCD 控制器深度对比
科技·单片机·嵌入式硬件·mcu·lcd驱动
ltqshs5 天前
STM32-FreeRTOS函数名规律总结
mcu
qyyyyy5706 天前
芯片 Datasheet PDF 怎么翻译?寄存器表、时序图和电气参数阅读实战
嵌入式硬件·mcu·database·机器翻译·石墨文档