分析连接脚本的语法规则

/* ----------------------------------------------------------------------------
* 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. centos 启动 oracle

    source .bash_profile su - oracle //切换到自己的oracle账户   lsnrctl start //启动oracle监听   sqlplus /nolog //登录 ...

  2. 201671010403 陈倩倩 实验十四 团队项目评审&课程学习总结

    一:实验名称:团队项目评审&课程学习总结 二:实验目的与要求 (1)掌握软件项目评审会流程: (2)反思总结课程学习内容. 三:实验步骤 任务一:按照团队项目结对评审名单,由项目组扮演乙方,结 ...

  3. 201671010425邱世妍 团队评审&课程总结

    实验十四 团队项目评审&课程学习总结 项目 内容 这个作业属于哪个课程 http://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cn ...

  4. 《快活帮》第九次团队作业:【Beta】Scrum meeting 2

    项目 内容 这个作业属于哪个课程 2016计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十三 团队作业9:BETA冲刺与团队项目验收 团队名称 快活帮 作业学习目标 (1)掌 ...

  5. oracle row_number() over(partition by .. order by ..)和rank() over(partition by .. order by ..) 和dense_rank() over(partition by .. order by ..)的相似点与区别

    新建一个测试表 create table dim_ia_test2(device_number varchar2(20),desc2 varchar2(20)) 插入数据后得到: 一.oracle r ...

  6. hive Hive 2.0函数大全(中文版)(转)

    转自:https://www.cnblogs.com/MOBIN/p/5618747.html#1 摘要 Hive内部提供了很多函数给开发者使用,包括数学函数,类型转换函数,条件函数,字符函数,聚合函 ...

  7. 最后一个对象属性后边不要加豆号的bug,血淋淋的教训啊,模块化开发IE7下的严重错误,养成好习惯

    最近总是写滚动图效果,重复的劳动后,决定写一个滚动图的封装插件.结果写完后在其他浏览器都可以用,却IE7下毫无反应.反复测试各种检查后,发现竟然是在参数对象最后一个属性后多加了个逗号,结果就死在了IE ...

  8. redux沉思录

    要素:store.reducer.dispatch/subscribe connect:将业务逻辑剥离到容器类,数据的双向绑定: 数据.操作.UI分离.命令封装 核心思想:对共享状态的维护: 核心代码 ...

  9. PHP - assert()

    Find and exploit the vulnerability to read the file .passwd.-------------查找并利用此漏洞读取文件.passwd. assert ...

  10. LeetCode 490. The Maze

    原题链接在这里:https://leetcode.com/problems/the-maze/ 题目: There is a ball in a maze with empty spaces and ...