LD文件详解

周末卷起来,讲个知识点很散的LD文件,这东西难度完全看原来的LD文件怎么写,我们顶多就是改改,从零开始写的话,人都要到异世界生活了。

说在前面

它不像代码一样都是要定义的,大部分都是标号,没定义过的标号第一次出现就是给他定义。

它的注释一般是C语言那种/**/,其他的不知道能不能用

它有几个大块,花括号{}外面部分、MEMORY部分、SECTIONS部分、其他带花括号的部分。

花括号{}外面部分

这些比较简单,就是一些宏定义。

ENTRY入口地址

复制代码
ENTRY(Reset_Handler)

以Reset_Handler作为进程执行的第一条用户空间的指令在进程地址空间的地址,简单来说就是代码从这里开始执行,Reset_Handler一般在startup之类的汇编文件里面写着。

DEFINED检查定义

复制代码
HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x00000400;

DEFINED(heap_size) 检查__heap_size__是否已经被定义,如果有定义就返回1,没定义就返回0。但是这里后面跟着? heap_size : 0x00000400;意义就变了,变成了像C语言一样"DEFINED(heap_size) ? heap_size : 0x00000400"成了一个整体。

如果__heap_size__有定义就返回__heap_size__的值,没定义就返回0x00000400。

MEMORY部分

就是MEMORY然后用花括号括住的部分,像刻光盘一样,给你的芯片分个区,这里仅仅只是分区,不会塞东西进去。

复制代码
MEMORY
 {
   iROM_0         : ORIGIN = 0x00000000,  LENGTH = 1206k
   iRAM_0         : ORIGIN = 0x04000000,  LENGTH = 32k
 }

有像上面这样写的最简单的,分个iROM_0区域,0x00000000开始,长度为1206k。

复制代码
MEMORY
{
  /* Flash */
  m_interrupts          (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000400
  m_text                (RX)  : ORIGIN = 0x00000410, LENGTH = 0x000EBBF0

  /* SRAM */
  m_data_2              (RW)  : ORIGIN = 0x1FFF4800, LENGTH = 0x0001A000
  MagicFlag             (RW)  : ORIGIN = 0x2000EB00, LENGTH = 0x00000500
}

有像这样写得详细一点的,分开flash和RAM区域,还标注清楚权限。

SECTIONS部分

SECTIONS是最重要的,不仅细化了MEMORY的分区,还能嵌套别的{}。SECTIONS里面的{}也叫SECTIONS。

复制代码
SECTIONS
 {
/* Start of internal ROM area (iROM_0) */
  .intvect  align (512)                 :>iROM_0  /* start of interrupt vector */
  .intvect_end  0x00200                 :>.       /* end   of interrupt vector */
  EIINTTBL  align (4)                   :>.
  .text     align(4)                    :>.      /* program code area */

  .romdata  ROM(.data)                  :>.      /* constant data to initialize variables (copied to RAM at startup)*/
  .romzdata ROM(.zdata)                 :>.      /* constant data to initialize variables in ZDA area (copied to RAM at startup)*/

  __top_of_iROM_0 = MEMENDADDR(iROM_0);
}

这里只提取了iROM_0的部分,我们逐句解析。

复制代码
  .intvect  align (512)                 :>iROM_0
  .intvect_end  0x00200                 :>. 
  EIINTTBL  align (4)                   :>.
  .text     align(4)                    :>.      /* program code area */

先分了个叫".intvect"的中断向量表的区域出来,这里的SECTIONS名前面都要加点号。align是个对齐的命令,要开512字节的空间并且将里面中断向量表的内容对齐。:>就是放入的意思。把这512字节放到iROM_0里面,也就是上面的MEMORY里面的首地址0x00000000。

.就是当前地址的意思,由于上面已经占用了512字节,也就是0x200,那么下面的.会自动向后移动512字节。那就是把intvect_end放到0x200的位置。

后面的自然都懂

复制代码
  .romdata  ROM(.data)                  :>.      /* constant data to initialize variables (copied to RAM at startup)*/
  .romzdata ROM(.zdata)                 :>.      /* constant data to initialize variables in ZDA area (copied to RAM at startup)*/

其他带花括号的部分

相关推荐
戴为沐44 分钟前
Linux内存扩容指南
linux
zylyehuo11 小时前
Linux 彻底且安全地删除文件
linux
用户805533698031 天前
主线 U-Boot 上 RK3506:和闭源 rkbin 拔河的三个隐性契约
linux·嵌入式
用户034095297911 天前
linux fcitx 5 雾凇拼音 设置在中文输入法下仍然输入英文标点
linux
乘云数字DATABUFF1 天前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
Web3探索者3 天前
可视化服务器管理和传统命令行区别是什么?新手教程:Linux 运维到底该用图形界面还是 SSH 命令行?
linux·ssh
zylyehuo3 天前
Linux系统中网线与USB网络共享冲突
linux
荣--3 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森3 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜4 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https