本文所使用工程由STM32CubeMX生成,使用芯片:STM32F103ZET6,基本只开了时钟。
ld连接脚本内容如下:

/*
*****************************************************************************
****  File        : LinkerScript.ld
**
**  Abstract    : Linker script for STM32F103ZETx Device with
**                512KByte FLASH, 64KByte RAM
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used.
**
**  Target      : STMicroelectronics STM32
**
**
**  Distribution: The file is distributed as is, without any warranty
**                of any kind.
**
**  (c)Copyright Ac6.
**  You may use this file as-is or modify it according to the needs of your
**  project. Distribution of this file (unmodified or modified) is not
**  permitted. Ac6 permit registered System Workbench for MCU users the
**  rights to distribute the assembled, compiled & linked contents of this
**  file as part of an application binary file, provided that it is built
**  using the System Workbench for MCU toolchain.
**
*****************************************************************************
*//* Entry Point */
ENTRY(Reset_Handler)/* Highest address of the user mode stack */
_estack = 0x20010000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack *//* Specify the memory areas */
MEMORY
{RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 64K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 512K
}/* Define output sections */
SECTIONS
{/* The startup code goes first into FLASH */.isr_vector :{. = ALIGN(4);KEEP(*(.isr_vector)) /* Startup code */. = ALIGN(4);} >FLASH/* The program code and other data goes into FLASH */.text :{. = ALIGN(4);*(.text)           /* .text sections (code) */*(.text*)          /* .text* sections (code) */*(.glue_7)         /* glue arm to thumb code */*(.glue_7t)        /* glue thumb to arm code */*(.eh_frame)       /*                        */KEEP (*(.init))KEEP (*(.fini)). = ALIGN(4);_etext = .;        /* define a global symbols at end of code */} >FLASH/* Constant data goes into FLASH */.rodata :{. = ALIGN(4);*(.rodata)         /* .rodata sections (constants, strings, etc.) */*(.rodata*)        /* .rodata* sections (constants, strings, etc.) */. = ALIGN(4);} >FLASH.ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH.ARM : {__exidx_start = .;*(.ARM.exidx*)__exidx_end = .;} >FLASH.preinit_array     :{PROVIDE_HIDDEN (__preinit_array_start = .);KEEP (*(.preinit_array*))PROVIDE_HIDDEN (__preinit_array_end = .);} >FLASH.init_array :{PROVIDE_HIDDEN (__init_array_start = .);KEEP (*(SORT(.init_array.*)))KEEP (*(.init_array*))PROVIDE_HIDDEN (__init_array_end = .);} >FLASH.fini_array :{PROVIDE_HIDDEN (__fini_array_start = .);KEEP (*(SORT(.fini_array.*)))KEEP (*(.fini_array*))PROVIDE_HIDDEN (__fini_array_end = .);} >FLASH/* used by the startup to initialize data */_sidata = LOADADDR(.data);/* Initialized data sections goes into RAM, load LMA copy after code */.data : {. = ALIGN(4);_sdata = .;        /* create a global symbol at data start */*(.data)           /* .data sections */*(.data*)          /* .data* sections */. = ALIGN(4);_edata = .;        /* define a global symbol at data end */} >RAM AT> FLASH/* Uninitialized data section */. = ALIGN(4);.bss :{/* This is used by the startup in order to initialize the .bss secion */_sbss = .;         /* define a global symbol at bss start */__bss_start__ = _sbss;*(.bss)*(.bss*)*(COMMON). = ALIGN(4);_ebss = .;         /* define a global symbol at bss end */__bss_end__ = _ebss;} >RAM/* User_heap_stack section, used to check that there is enough RAM left */._user_heap_stack :{. = ALIGN(8);PROVIDE ( end = . );PROVIDE ( _end = . );. = . + _Min_Heap_Size;. = . + _Min_Stack_Size;. = ALIGN(8);} >RAM/* Remove information from the standard libraries *//DISCARD/ :{libc.a ( * )libm.a ( * )libgcc.a ( * )}.ARM.attributes 0 : { *(.ARM.attributes) }
}

首先链接脚本使用命令 ENTRY 指明了程序入口 Reset_Handler 也就是代码是从复位中断开始执行的。
其次,定义了三个 变量 ,它们含义如下:

往下又用 MEMORY 去定义了两个内存区:

这里内存名称后面的括号里代表权限:
x:可运行
r:可读
w:可写
可以看到这里RAM是可运行可读可写,而FLASH只可运行可读。有人可能会说32的FLASH是可以写的,但这里的权限只针对链接脚本,并不代表代码执行。
下面一大段都属于命令 SECTIONS,两个花括号里面的内容就是链接规则。
如:

SECTIONS
{.text :        /*最终输出的.text段*/{*(.text)    /*所有匹配文件中的.text段*/}.data : {*(.data)}.bss : {*(.bss)}
}

这里就是链接脚本的核心功能,我们先不考虑每个段的功能,先了解一下链接脚本到底用来干什么。因为一个工程内可能有多个.c文件,比如你代码里面一共3个文件:分别是 main.cusart.cstart.s 。很明显一个主程序,一个串口驱动,一个启动文件。在实际编译中,会把它们分别编译为 main.ousart.ostart.o ,假如每个.o文件中都包含.text、.data、.bss段,但是我们知道,程序最后烧入MCU是只有一个文件,这里就涉及到段的合并,也就是上面的命令所实现的功能,把每个.o文件中的相同段合一。第一个冒号左边的.text就是合并后的.text段,它是由符合花括号内规则的所有内容合并得到的,在刚才的例子里就是 main.ousart.ostart.o 中的.text段。*号代表通配符,这里它没有前缀和后缀,也没有 [] 内容修饰,所以它代表所有匹配文件。知道这一点我们可以往下分析。

这里看到,中断向量表被链接到段 .isr_vector 内,. 表示当前虚拟内存地址(location counter),ALIGN(4)表示四字节对齐。这里使用了 KEEP 命令来保存所有文件中的 .isr_vector 内容,即使它们没有被调用。也就是在保存中断向量前做四字节对齐,保存后做四字节对齐。内容存在上面MEMORY中定义的FLASH中。
下面是代码段:

只读数据段:

外设拓展内存:

栈展开信息段:



注意这里 LOADADDR 返回的是加载地址,而不是虚拟地址。


最后一个用于设置过特殊属性数据的段

不做具体解释,官方解释:ARM-attributes

更新 2022-03-28

之前关于.ld链接脚本中某些段的解释是错的,现更正:
.ARM.exidx.ARM.extab


.ARM.attributes主要包含构建属性

参考:
ARM官方EHABIAAELF

推荐书籍:
《程序员的自我修养–链接、装载与库》

(GCC)STM32CubeMX生成的ld链接脚本详解相关推荐

  1. Rt-thread [三] link.lds链接脚本详解

    Rt-thread [三] link.lds文件详解 前言 程序编译流程 什么是链接 基本概念 RT-thread stm32f407 link.lds链接脚本详解 资料 前言   开一个专题,记录自 ...

  2. Linux下的lds链接脚本详解

    一. 概论 每一个链接过程都由链接脚本(linker script, 一般以lds作为文件的后缀名)控制. 链接脚本主要用于规定如何把输入文件内的section放入输出文件内, 并控制输出文件内各部分 ...

  3. linux下lds链接脚本详解

    转载自:http://linux.chinaunix.net/techdoc/beginner/2009/08/12/1129972.shtml 一. 概论 每一个链接过程都由链接脚本(linker ...

  4. RISC-V MCU ld链接脚本说明

    1.什么是ld链接脚本? 通常,程序编译的最后一步就是链接,此过程根据"*.ld"链接文件将多个目标文件(.o)和库文件(.a)输入文件链接成一个可执行输出文件(.elf).涉及到 ...

  5. 【转载】CodeWarrior IDE使用tips之prm链接文件详解(自定义存储器分区以及自定义RAM数据初始化与在RAM中运行函数)...

    CodeWarrior IDE使用tips之prm链接文件详解(自定义存储器分区以及自定义RAM数据初始化与在RAM中运行函数) 2017-08-19 胡恩伟 汽车电子expert成长之路 内容提要 ...

  6. sshd系统自带启动脚本详解

    SSH 为 Secure Shell 的缩写.sshd服务是linux系统中最经常使用的服务之一.由于其规避了明文传送口令.内容本文及中间人***的安全隐患,因此经常作为远程管理系统的首选方案.虽然各 ...

  7. shell脚本详解(十二)——Here Document免交互及Expect自动化交互

    shell脚本详解(十二)--Here Document免交互及Expect自动化交互 一.Here Document 免交互 1.格式 2.注意事项 3.免交互方式实现对行数的统计,将要统计的内容置 ...

  8. linux 的文件软链接隐藏,Linux inode及硬链接软链接详解

    Linux inode及硬链接软链接详解 York • 2020 年 09 月 28 日 Loading... 操作系统的文件数据除了实际内容之外,通常含有非常多的属性,例如 `Linux`操作系统的 ...

  9. php 自动获取头像,PHP_WordPress中用于获取及自定义头像图片的PHP脚本详解,get_avatar()(获取头像) get_avat - phpStudy...

    WordPress中用于获取及自定义头像图片的PHP脚本详解 get_avatar()(获取头像)get_avatar() 函数用来获取置顶邮箱或者用户的头像代码,在评论列表中非常常用. 这个函数提供 ...

最新文章

  1. Laravel 查询某天数据 whereDate
  2. dnastar拼接反向互补序列_一起看流畅的python:序列构成的数组
  3. 运维的最终目标是什么?
  4. 对 makefile 中 $(MAKE) 的学习体会
  5. 洛谷P3607:Subsequence Reversal P(区间dp)
  6. 5193. 删除字符使字符串变好
  7. eclipse 中文_谁说API必须用英文?中文API的Java库可以有!
  8. 利用cors,实现js跨域访问Tomcat下资源
  9. linux系统修改只读文件权限如(etc/hosts)文件
  10. mysql2008 精简版_精简版 SqlServer2008 的安装和使用
  11. windows无法新建计算机对象,无法创建文件,详细教您无法新建文件夹怎么办
  12. 堪比端游 欧美十大RPG网页游戏推荐
  13. 一文带你揭秘并实现“大数据杀熟”背后的逻辑!
  14. VMwarex虚拟机打不开:“指定的文件不是虚拟磁盘”
  15. socket: (10106) 无法加载或初始化请求的服务提供程序。
  16. 测试基础-测试的定义及原则?
  17. 【Cocos2d-x】物理引擎使用入门
  18. libnids中TCP/IP栈实现细节分析——TCP会话重组
  19. 足球比赛常用英语单词集锦
  20. 一文解决机器学习中的过拟合与欠拟合问题(正则化,数据增强,Dropout)

热门文章

  1. 【新闻资讯】淘宝客达人:网赚盈利模式之淘宝客盈利技巧分享
  2. A Cross-Modal Image and Text Retrieval Method Based on Efficient Feature Extraction and Interactive
  3. ajax技术优点和缺点,介绍Ajax技术
  4. 超级基金投资术 用10万赚100万!
  5. 2016阿里安全峰会(附峰会议题一览表)
  6. noi字符串11:潜伏者题解
  7. word2vec词向量原理
  8. pythonif语句怎么换行输入_李沁和李易峰演的电视剧叫什么名字
  9. python脚本实现qq邮箱发送邮件
  10. python创意编程培训 体会_省人工智能和创意编程教学研讨会学习心得