当前位置:网站首页>Stm32cubeide link script explanation
Stm32cubeide link script explanation
2022-07-23 07:30:00 【coder.mark】
One 、 Purpose
I believe many friends use it for the first time STM32CubeIDE When developing, we encounter GNU LD The script is confused , stay Keil In, we will use distributed loading files for similar operations , that GNU LD What is the link script used by the linker ?
This article is based on CUBIEIDE Medium ld Script description links the composition of the script file .
Two 、 Introduce
Reference documents
GNU LD Scripting command language ( One )_coder.mark The blog of -CSDN Blog
https://blog.csdn.net/tianizimark/article/details/125865933 GNU LD Scripting command language ( Two )_coder.mark The blog of -CSDN Blog
https://blog.csdn.net/tianizimark/article/details/125899178
3、 ... and 、 actual combat
Now let's explain the specific link script .
/*
******************************************************************************
**
** File : LinkerScript.ld
**
** Author : STM32CubeIDE
**
** Abstract : Linker script for STM32H7 series
** 128Kbytes FLASH and 1056Kbytes 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.
**
*****************************************************************************
** @attention
**
** Copyright (c) 2022 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* 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
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
}
/* 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 */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM_D1 AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_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_D1
/* 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_D1
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
ENTRY(RESET_Handler) Defines the address of the first instruction executed by the program , That is, reset the interrupt processing function .
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); Defines a name _estack The symbol of , Its value is RAM_D1 The last address of the district .ORIGIN Function is used to REGION The first address ,LENGTH Used to obtain REGION The length of .
_Min_Heap_Size = 0x200 ; Defines the minimum heap size
_Min_Stack_Size = 0x400; Defines the minimum stack size
MEMORY Each of the Region First address and size of , From the script STM32H750 There are the following address spaces
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64KSECTIONS Defines how input segments map to output segments , Let's take a look at the first output segment description :
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASHPut all... In the input file .isr_vector Segments are put in the output file .isr_vector In the paragraph , And set the address of the output segment to Flash Region The first address ;KEEP The function of the command is to keep this input segment in the output file even if it is not referenced by other input segments ;ALIGN(4) It refers to 4 Byte alignment ; The current address here is Flash Region The first address .
This output segment describes the use of ">FLASH" Is used to specify the VMA Address , therefore location counter The initial value of is no longer 0, But in FLASH REGION In the address space of , And because of .isr_vector Output segment is FLASH REGION The first output segment of , therefore .isr_vector Just put it in FLASH In the first address of .
/* 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 */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM_D1 AT> FLASH
In the above example, we define an output segment .data, One thing to note is that >RAM_D1 AT> FLASH
among >RAM_D1 Refers to the output segment VMA The address is at RAM_D1 In the address space of , That is to say, the content of this section should be copied to RAM_D1 In the address space of ;
AT> FLASH Refers to the output segment LMA The address is at FLASH in , In other words, these data need to be burned in the specified Flash In the address space ;
About LMA and VMA Please see the description in the reference document for the difference between , Just remember RW The segment needs to be loaded into Flash Medium LMA address , When the program is executed, the data needs to be from Flash Copied to the RAM Medium VMA address .
KEEP (*(SORT(.fini_array.*)))When describing the output segment , We can sort the input segments and then map them to the output segment , Here SORT keyword , That is, all input segments meet .fini_array. The first segment is sorted alphabetically , Then map to the output segment ;KEEP The meaning of has been explained above .
Discard unwanted segments
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }Literally, it means to input all the .ARM.attributes All the paragraphs are put in .ARM.attributes In the output segment , And set up VMA by 0, Because we won't access any address in the code 0 The symbol of ( Function or data ), So it's a little similar to "/DISCARD/". If you know the exact meaning, you can leave a message and tell me , thank you .
Through the above explanation , I believe you should have a preliminary understanding , If there is anything unclear , Please read the resources carefully again .
边栏推荐
- Image processing solution veimagex technology evolution Road
- Inside the hard core of LAN SDN technology - 14 three from things to people - SDN enters the campus network
- Analyse de la stratégie de lecture et d'écriture du cache
- 0day attack path prediction method based on network defense knowledge map
- C language file operation (including all knowledge points, detailed explanation of related functions and codes)
- 对比学习下的跨模态语义对齐是最优的吗?---自适应稀疏化注意力对齐机制 IEEE Trans. MultiMedia
- LAN SDN technology hard core insider - what's in the prequel CPU?
- 奇瑞艾瑞泽8产品力超能打,“全优”可不是白叫的
- 在项目开发中的Logback日志框架技术
- 聪明人的游戏提高篇:第三章第二课:因子个数(factor)
猜你喜欢

Attack and defense scheme based on Ethereum status database

After the applet wx.setstoragesync, sometimes it can't get data with getstoragesync

程序员45岁之后,绝大部分都被淘汰吗?真相寒了众人的心

iQOO 10系列来袭 OriginOS原系统强化手机体验

深度学习模型的版权保护研究综述

A survey of copyright protection research on deep learning model

一文理解分布式开发中的服务治理

网络空间拟态防御发展综述:从拟态概念到“拟态+”生态

面向商用活体检测平台的鲁棒性评估

说说Flutter中的RepaintBoundary
随机推荐
After the applet wx.setstoragesync, sometimes it can't get data with getstoragesync
接口-Fiddler-简介与安装
说说Flutter中的RepaintBoundary
AE common expression summary "suggestions collection"
Vector3.Lerp
IP第二次实验 MGRE OSPF
浅析缓存的读写策略
每日刷题记录 (三十一)
上采样方式(反卷积、插值、反池化)
开源2周年,openGauss Developer Day 2022全程亮点回顾!
uniapp切换tab栏显示不同页面并记住页面位置和上拉获取新数据
Ambire Gas Tank 推出独家 NFT 投放
What is the difference between GPU and CPU? Introduction to the meaning of GPU in different computers
什么是真正的 HTAP ?(二)挑战篇
iQOO 10系列来袭 OriginOS原系统强化手机体验
图像处理解决方案 veImageX 技术演进之路
Redis common basic configuration files
聪明人的游戏提高篇:第三章第二课:因子个数(factor)
ES6解决异步问题
[FAQ] common reasons and solutions for the failure of in app payment services to pull up the payment page