分析连接脚本的语法规则

/* ----------------------------------------------------------------------------
* Memory linker description
* ------------------------------------------------------------------------- */
MEMORY
{
/* ROM区,只读, 起始地址0x00000000, 长度4K */
ROM (r) : ORIGIN = 0x00000000, LENGTH = 4K
/* FLASH区, 读,写,可执行, 起始地址0x00100000, 长度380K*/
FLASH (xrw) : ORIGIN = 0x00100000, LENGTH = 380K
/* PRAM , 32K */
PRAM (xrw) : ORIGIN = 0x00200000, LENGTH = 32K DRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 24K
DRAM_DSP (xrw) : ORIGIN = 0x20006000, LENGTH = 48K
DRAM_BB (xrw) : ORIGIN = 0x20012000, LENGTH = 16K
} /* ----------------------------------------------------------------------------
* Stack related defines and provided variables
* ------------------------------------------------------------------------- */
/* 计算stack的地址 */
__stack = ORIGIN(DRAM) + LENGTH(DRAM);
/* 全局变量__stack, c语言可以应用 */
PROVIDE ( __stack = __stack ) ; /*
* Default stack sizes.
* These are used by the startup in order to allocate stacks
* for the different modes.
*/ __Main_Stack_Size = 1024 ;
PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ; __Main_Stack_Limit = __stack - __Main_Stack_Size ;
PROVIDE ( _Main_Stack_Limit = __Main_Stack_Limit ) ; /* ----------------------------------------------------------------------------
* Heap related defines and provided variables
* ------------------------------------------------------------------------- */
PROVIDE ( __Heap_Begin__ = __noinit_end__ ) ;
PROVIDE ( __Heap_Limit__ = __stack - __Main_Stack_Size ) ; /*
* The entry point is informative, for debuggers and simulators,
* since the Cortex-M vector points to it anyway.
*/
/* 指定可执行文件的起始代码段是Reset_Handler */
ENTRY(Reset_Handler) /*
* As is the VTOR register, we refer to it in startup documentation
*/
__VTOR = 0xE000ED08; /* ----------------------------------------------------------------------------
* Section definitions
* ------------------------------------------------------------------------- */
SECTIONS
{
/*
* For Cortex-M devices, the beginning of the startup code is stored in
* the .interrupt_vector section, which goes to FLASH
*/
/* DEFINED判断括号内的__app_rom_start,是否在全局符号表内,并且定义了,是就返回1,否返回0
* 再根据DEFINED结果进行判断__rom_start的值,是__app_rom_start,还是ORIGIN(FLASH)
*/
__rom_start = DEFINED(__app_rom_start) ? __app_rom_start : ORIGIN(FLASH);
/* 计算image的大小 */
__image_size = __data_init__ + SIZEOF(.data) - __rom_start;
/* .text代码段, 保存在FLASH中,FLASH起始地址0x0010000*/
.text __rom_start :
{
/* 四字节对齐 */
. = ALIGN(4);
/* 强制链接器保留一些特定的section */
KEEP(*(.interrupt_vector)) /*
* This section is here to store the startup code immediately after
* the interrupt vectors, as required by the program ROM.
*/
/* 所有文件的reset段,都放在interrupt_vector段后面 */
*(.reset) /*
* FOTA BootLoader descriptor
*/
*(.rodata.fota.image-size)
KEEP(*(.rodata.fota.build-id)) /*
* FOTA version descriptor
*/
/* 所有的.rodata.boot.version section 放到.text section里面*/
*(.rodata.boot.version) /* Pre-initialization Code */
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start__ = .); /* System initialization and the platform initialization (if present)
* should be first */
KEEP(*(.preinit_array_sysinit .preinit_array_sysinit.*))
KEEP(*(.preinit_array_platform .preinit_array_platform.*)) /* Pre-initialization functions (to be executed before C++
* constructors are run) */
KEEP(*(.preinit_array .preinit_array.*)) PROVIDE_HIDDEN (__preinit_array_end__ = .); /* Initialization Code */
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start__ = .); KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end__ = .); /*
* The program code is stored in the .text section,
* which goes to FLASH.
*/
. = ALIGN(4);
/* 所有的文件的.text section*/
*(.text .text.*) /* all remaining code */
/* 所有文件的.rodata section */
*(.rodata .rodata.*) /* read-only data (constants) */ . = ALIGN(4);
__dsp_start__ = . ;
KEEP(*(.dsp .dsp.*)) /* all remaining DSP code */
__dsp_end__ = . ;
/* 四字节对齐 */
. = ALIGN(4);
/* .text全部链接到FLASH里面,Flash是前面MEMORY里面定义的,起始地址是0x00100000 */
} >FLASH /*
* This address is used by the startup code to
* initialize the .data section.
*/
. = ALIGN(4);
/* 将定位符号'.'的值赋给__data_init */
/* 也就是说__data_init__放在.text段的后面 */
__data_init__ = .; /* Place the SystemClock variable needed for CMSIS in a place that is
* compatible with the ROM's placement of this variable so that the
* variable can be used by CMSIS and the ROM's flash write libary */
.systemclock (NOLOAD) :
{
. = ALIGN(4);
KEEP(*(.systemclock))
/* 保存到DRAM中 */
} > DRAM /*
* The initialized data section.
* The program executes knowing that the data is in the RAM
* but the loader puts the initial values in the FLASH (inidata).
* It is one task of the startup to copy the initial values from
* FLASH to RAM.
*/
/* 查看__app_ram_start是否定义,并给__ram_start赋值 */
__ram_start = DEFINED(__app_ram_start) ? __app_ram_start : .;
/* .data数据段 */
/* AT表示加载地址或者存储地址,指程序编译之后存放的地址,一般在ROM或者FLASH中 */
/* 运行的时候,从AT指定的地址__data_init__中赋值到_ram_start中运行 */
/* 从FLASH中复制到RAM里面运行 */
.data __ram_start : AT ( __data_init__ )
{
. = ALIGN(4); /* This is used by the startup code to initialize the .data section */
__data_start__ = . ;
*(.data_begin .data_begin.*)
*(.data .data.*)
*(.data_end .data_end.*)
. = ALIGN(4); /* This is used by the startup code to initialize the .data section */
__data_end__ = . ;
} >DRAM /*
* The uninitialized data section. NOLOAD is used to avoid
* the "section `.bss' type changed to PROGBITS" warning
*/
/* .bss未初始化的数据段, 存放在DRAM中 */
.bss (NOLOAD) :
{
. = ALIGN(4);
__bss_start__ = .; // 把__bss_start_段赋值当前位置,bss段的起始位置
*(.bss_begin .bss_begin.*) // 所有的bss_begin和bss_begin.*段放到bss里面 *(.bss .bss.*) // 所有文件的.bss和.bss.*段放在bss_begin,bss_begin.*后面
*(COMMON) // COMMON放在.bss,.bss.*后面 *(.bss_end .bss_end.*) // 所有文件的.bss_end, .bss_end.* 放在COMMON后面
. = ALIGN(4);
__bss_end__ = .; // 把__bss_end__段赋值为当前位置,结束位置
} >DRAM .noinit (NOLOAD) :
{
. = ALIGN(4);
__noinit_start__ = .; *(.noinit .noinit.*) . = ALIGN(4) ;
__noinit_end__ = .;
} > DRAM /* Check if there is enough space to allocate the main stack */
._stack (NOLOAD) :
{
. = ALIGN(4); . = . + __Main_Stack_Size ; // 计算栈的大小放到DRAM中 . = ALIGN(4);
} >DRAM
}

ARM 链接脚本分析的更多相关文章

  1. u-boot链接脚本分析

    eclipse 64位下载地址:http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release ...

  2. Linux 链接脚本分析

    作者:答疑助手lizuobin 原文: https://blog.csdn.net/lizuobin2/article/details/51779064 在前面学习的过程中,看代码时遇到 arch_i ...

  3. arm链接脚本

    一. 为什么需要链接脚本 1.1. 从源码到可执行程序(主要有三个步骤:预编译.编译.链接) 1.1.1. 预编译 a. 预编译器执行.譬如C中的宏定义就是由预编译器处理,注释等也是由预编译器处理的. ...

  4. u-boot.lds 链接脚本分析(hi3515)

    目录:/u-boot_hi3515/board/hi3515v100 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm& ...

  5. 四、u-boot 链接脚本

    4.1 C语言中的段 编译器在编译程序的时候,将程序中的所有的元素分成了一些组成部分,各部分构成一个段,所以说段是可执行程序的组成部分. 代码段:代码段就是程序中的可执行部分,直观理解代码段就是函数堆 ...

  6. arm裸板驱动总结(makefile+lds链接脚本+裸板调试)

    在裸板2440中,当我们使用nand启动时,2440会自动将前4k字节复制到内部sram中,如下图所示: 然而此时的SDRAM.nandflash的控制时序等都还没初始化,所以我们就只能使用前0~40 ...

  7. 驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址

    驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址 最近重新看了乾龙_Heron的<ARM 上电启动及 Uboot 代码分析>(下简称<代码分析>) ...

  8. makefile使用.lds链接脚本以及 $@ ,$^, $,< 解析

    先来分析一个简单的.lds链接脚本 例1,假如现在有head.c init.c nand.c main.c这4个文件: 1.1 首先创建链接脚本nand.lds: SECTIONS { firtst ...

  9. makefile使用.lds链接脚本以及 $@ ,$^, $,< 解析【转】

    转自:http://www.cnblogs.com/lifexy/p/7089873.html 先来分析一个简单的.lds链接脚本 例1,假如现在有head.c init.c nand.c main. ...

随机推荐

  1. JAVA分页工具类

    最近写了一个代码生成工具,分享下该工具下的分页工具 一.分页工具类 package com.qy.code.api.page; import java.io.Serializable; import ...

  2. 【Git】Git如何合并某一次commit的内容到指定分支

    一.我是在什么场景下会用到该Git操作 当某同事,将开发分支dev2合并到开发分支dev1时(两个不同的功能,不能合并),其他同事不知情的情况下,继续在dev1上开发并提交了代码. 后面发现了该合并, ...

  3. VUE 动态菜单管理

    业务场景 不同的用户登录,看到的菜单会不一样,因此需要根据不同人登录的身份去后端获取菜单. 实现思路 1.构建路由 2.从后端构建菜单 3.前端获取菜单 4.前端渲染菜单 1.构建路由. export ...

  4. Spring实战(第4版).pdf - 百度云资源

    http://www.supan.vip/spring%E5%AE%9E%E6%88%98 Spring实战(第4版).pdf 关于本书 Spring框架是以简化Java EE应用程序的开发为目标而创 ...

  5. 后台根据html邮件模板发送邮件

    HTML邮件模板: xxxxxxx 在线模板的方式: String fileName = "http://localhost:8080/xxxxxxx.html"; URL url ...

  6. FileReader 事件用法

    FileReader对象采用异步方式读取文件,在不同的读取阶段会触发不同的事件. 事件列表: (1).abort事件:读取中断或调用reader.abort()方法时触发. (2).error事件:读 ...

  7. 29、Python程序中的进程操作(multiprocess.process)

    一.multiprocess模块 multiprocess不是一个模块而是python中一个操作.管理进程的包. 子模块分为四个部分: 创建进程部分 进程同步部分 进程池部分 进程之间数据共享 二.m ...

  8. Ofbiz项目学习——阶段性小结——视图

    一.简要介绍 1.按照SQL的视图概念:在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表.视图包含行和列,就像一个真实的表.视图中的字段就是来自一个或多个数据库中的真实的表中的字段. 2. ...

  9. 在swift项目中若要通过pod引入第三方的swift项目,必须加上use_frameworks!

    因为swift没法打.a https://www.jianshu.com/p/ac629a1cb8f5

  10. Ad-hoc--拉丁文--for this purpose only

    Ad-hoc这个词来源于拉丁语,在百度上解释为“for this purpose only”, 在wiki上解释为“for this”,其中文在wiki上被解释成包含“特设的.特定目的的(地).即席的 ...