分析连接脚本的语法规则

  1. /* ----------------------------------------------------------------------------
  2. * Memory linker description
  3. * ------------------------------------------------------------------------- */
  4. MEMORY
  5. {
  6. /* ROM区,只读, 起始地址0x00000000, 长度4K */
  7. ROM (r) : ORIGIN = 0x00000000, LENGTH = 4K
  8. /* FLASH区, 读,写,可执行, 起始地址0x00100000, 长度380K*/
  9. FLASH (xrw) : ORIGIN = 0x00100000, LENGTH = 380K
  10. /* PRAM , 32K */
  11. PRAM (xrw) : ORIGIN = 0x00200000, LENGTH = 32K
  12. DRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 24K
  13. DRAM_DSP (xrw) : ORIGIN = 0x20006000, LENGTH = 48K
  14. DRAM_BB (xrw) : ORIGIN = 0x20012000, LENGTH = 16K
  15. }
  16. /* ----------------------------------------------------------------------------
  17. * Stack related defines and provided variables
  18. * ------------------------------------------------------------------------- */
  19. /* 计算stack的地址 */
  20. __stack = ORIGIN(DRAM) + LENGTH(DRAM);
  21. /* 全局变量__stack, c语言可以应用 */
  22. PROVIDE ( __stack = __stack ) ;
  23. /*
  24. * Default stack sizes.
  25. * These are used by the startup in order to allocate stacks
  26. * for the different modes.
  27. */
  28. __Main_Stack_Size = 1024 ;
  29. PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ;
  30. __Main_Stack_Limit = __stack - __Main_Stack_Size ;
  31. PROVIDE ( _Main_Stack_Limit = __Main_Stack_Limit ) ;
  32. /* ----------------------------------------------------------------------------
  33. * Heap related defines and provided variables
  34. * ------------------------------------------------------------------------- */
  35. PROVIDE ( __Heap_Begin__ = __noinit_end__ ) ;
  36. PROVIDE ( __Heap_Limit__ = __stack - __Main_Stack_Size ) ;
  37. /*
  38. * The entry point is informative, for debuggers and simulators,
  39. * since the Cortex-M vector points to it anyway.
  40. */
  41. /* 指定可执行文件的起始代码段是Reset_Handler */
  42. ENTRY(Reset_Handler)
  43. /*
  44. * As is the VTOR register, we refer to it in startup documentation
  45. */
  46. __VTOR = 0xE000ED08;
  47. /* ----------------------------------------------------------------------------
  48. * Section definitions
  49. * ------------------------------------------------------------------------- */
  50. SECTIONS
  51. {
  52. /*
  53. * For Cortex-M devices, the beginning of the startup code is stored in
  54. * the .interrupt_vector section, which goes to FLASH
  55. */
  56. /* DEFINED判断括号内的__app_rom_start,是否在全局符号表内,并且定义了,是就返回1,否返回0
  57. * 再根据DEFINED结果进行判断__rom_start的值,是__app_rom_start,还是ORIGIN(FLASH)
  58. */
  59. __rom_start = DEFINED(__app_rom_start) ? __app_rom_start : ORIGIN(FLASH);
  60. /* 计算image的大小 */
  61. __image_size = __data_init__ + SIZEOF(.data) - __rom_start;
  62. /* .text代码段, 保存在FLASH中,FLASH起始地址0x0010000*/
  63. .text __rom_start :
  64. {
  65. /* 四字节对齐 */
  66. . = ALIGN(4);
  67. /* 强制链接器保留一些特定的section */
  68. KEEP(*(.interrupt_vector))
  69. /*
  70. * This section is here to store the startup code immediately after
  71. * the interrupt vectors, as required by the program ROM.
  72. */
  73. /* 所有文件的reset段,都放在interrupt_vector段后面 */
  74. *(.reset)
  75. /*
  76. * FOTA BootLoader descriptor
  77. */
  78. *(.rodata.fota.image-size)
  79. KEEP(*(.rodata.fota.build-id))
  80. /*
  81. * FOTA version descriptor
  82. */
  83. /* 所有的.rodata.boot.version section 放到.text section里面*/
  84. *(.rodata.boot.version)
  85. /* Pre-initialization Code */
  86. . = ALIGN(4);
  87. PROVIDE_HIDDEN (__preinit_array_start__ = .);
  88. /* System initialization and the platform initialization (if present)
  89. * should be first */
  90. KEEP(*(.preinit_array_sysinit .preinit_array_sysinit.*))
  91. KEEP(*(.preinit_array_platform .preinit_array_platform.*))
  92. /* Pre-initialization functions (to be executed before C++
  93. * constructors are run) */
  94. KEEP(*(.preinit_array .preinit_array.*))
  95. PROVIDE_HIDDEN (__preinit_array_end__ = .);
  96. /* Initialization Code */
  97. . = ALIGN(4);
  98. PROVIDE_HIDDEN (__init_array_start__ = .);
  99. KEEP(*(SORT(.init_array.*)))
  100. KEEP(*(.init_array))
  101. PROVIDE_HIDDEN (__init_array_end__ = .);
  102. /*
  103. * The program code is stored in the .text section,
  104. * which goes to FLASH.
  105. */
  106. . = ALIGN(4);
  107. /* 所有的文件的.text section*/
  108. *(.text .text.*) /* all remaining code */
  109. /* 所有文件的.rodata section */
  110. *(.rodata .rodata.*) /* read-only data (constants) */
  111. . = ALIGN(4);
  112. __dsp_start__ = . ;
  113. KEEP(*(.dsp .dsp.*)) /* all remaining DSP code */
  114. __dsp_end__ = . ;
  115. /* 四字节对齐 */
  116. . = ALIGN(4);
  117. /* .text全部链接到FLASH里面,Flash是前面MEMORY里面定义的,起始地址是0x00100000 */
  118. } >FLASH
  119. /*
  120. * This address is used by the startup code to
  121. * initialize the .data section.
  122. */
  123. . = ALIGN(4);
  124. /* 将定位符号'.'的值赋给__data_init */
  125. /* 也就是说__data_init__放在.text段的后面 */
  126. __data_init__ = .;
  127. /* Place the SystemClock variable needed for CMSIS in a place that is
  128. * compatible with the ROM's placement of this variable so that the
  129. * variable can be used by CMSIS and the ROM's flash write libary */
  130. .systemclock (NOLOAD) :
  131. {
  132. . = ALIGN(4);
  133. KEEP(*(.systemclock))
  134. /* 保存到DRAM中 */
  135. } > DRAM
  136. /*
  137. * The initialized data section.
  138. * The program executes knowing that the data is in the RAM
  139. * but the loader puts the initial values in the FLASH (inidata).
  140. * It is one task of the startup to copy the initial values from
  141. * FLASH to RAM.
  142. */
  143. /* 查看__app_ram_start是否定义,并给__ram_start赋值 */
  144. __ram_start = DEFINED(__app_ram_start) ? __app_ram_start : .;
  145. /* .data数据段 */
  146. /* AT表示加载地址或者存储地址,指程序编译之后存放的地址,一般在ROM或者FLASH中 */
  147. /* 运行的时候,从AT指定的地址__data_init__中赋值到_ram_start中运行 */
  148. /* 从FLASH中复制到RAM里面运行 */
  149. .data __ram_start : AT ( __data_init__ )
  150. {
  151. . = ALIGN(4);
  152. /* This is used by the startup code to initialize the .data section */
  153. __data_start__ = . ;
  154. *(.data_begin .data_begin.*)
  155. *(.data .data.*)
  156. *(.data_end .data_end.*)
  157. . = ALIGN(4);
  158. /* This is used by the startup code to initialize the .data section */
  159. __data_end__ = . ;
  160. } >DRAM
  161. /*
  162. * The uninitialized data section. NOLOAD is used to avoid
  163. * the "section `.bss' type changed to PROGBITS" warning
  164. */
  165. /* .bss未初始化的数据段, 存放在DRAM中 */
  166. .bss (NOLOAD) :
  167. {
  168. . = ALIGN(4);
  169. __bss_start__ = .; // 把__bss_start_段赋值当前位置,bss段的起始位置
  170. *(.bss_begin .bss_begin.*) // 所有的bss_begin和bss_begin.*段放到bss里面
  171. *(.bss .bss.*) // 所有文件的.bss和.bss.*段放在bss_begin,bss_begin.*后面
  172. *(COMMON) // COMMON放在.bss,.bss.*后面
  173. *(.bss_end .bss_end.*) // 所有文件的.bss_end, .bss_end.* 放在COMMON后面
  174. . = ALIGN(4);
  175. __bss_end__ = .; // 把__bss_end__段赋值为当前位置,结束位置
  176. } >DRAM
  177. .noinit (NOLOAD) :
  178. {
  179. . = ALIGN(4);
  180. __noinit_start__ = .;
  181. *(.noinit .noinit.*)
  182. . = ALIGN(4) ;
  183. __noinit_end__ = .;
  184. } > DRAM
  185. /* Check if there is enough space to allocate the main stack */
  186. ._stack (NOLOAD) :
  187. {
  188. . = ALIGN(4);
  189. . = . + __Main_Stack_Size ; // 计算栈的大小放到DRAM中
  190. . = ALIGN(4);
  191. } >DRAM
  192. }

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. 逆向破解之160个CrackMe —— 021

    CrackMe —— 021 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...

  2. Linux学习23-Xftp上传文件显示乱码问题

    前言 当我们在windows新建一个文件,里面有中文时,使用Xftp上传到linux服务器上,会出现乱码问题. Windows的默认编码为GBK Linux的默认编码为UTF-8 Xftp上传文件乱码 ...

  3. CSS float 父元素高度自适应

    <html> <head><title></title><style type="text/css">*{margin: ...

  4. 【转】Web测试中定位bug方法

    在web测试过程中,经常会遇到页面中内容或数据显示错误,甚至不显示,第一反应就是BUG,进一步了解这个BUG的问题出在那里,是测试人员需要掌握的,可以简单的使用浏览器自带开发者工具.数据库工具配合去排 ...

  5. placeholder 效果的实现,input提示字,获取焦点时消失

    <!doctype html><html><head><meta charset="utf-8"><title>plac ...

  6. python--面向对象编程之学生选课系统练习

    1.系统目录结构 文件夹注解: bin--系统管理员和学生的主程序代码 config--系统的配置文件 db--系统的数据文件 admin--管理员的数据文件 student--学生的数据文件 lib ...

  7. 用插件maven-surefire-report-plugin生成html格式测试报告

    在默认情况下,执行maven test/maven package/maven install命令时会在target/surefire-reports目录下生成txt和xml格式的输出信息. 其实ma ...

  8. dotnetcore docker 简单运行

    今天试用了下mac 版本的dotnetcore sdk,发现还是很方便的,同时官方的容器运行方式,相对小了好多 同时使用多阶段构建的方式运行dotnetcore 安装sdk 下载地址: https:/ ...

  9. A|G\C003

    AGC003 A Wanna go back home = = https://agc003.contest.atcoder.jp/submissions/7910739 B Simplified m ...

  10. 洛谷 P4149 [IOI2011]Race-树分治(点分治,不容斥版)+读入挂-树上求一条路径,权值和等于 K,且边的数量最小

    P4149 [IOI2011]Race 题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 KK,且边的数量最小. 输入格式 第一行包含两个整数 n, Kn,K. 接下来 n - 1n−1 行 ...