女子世界杯_世界杯今日赛事 - fdrwxy.com SPACE


周末不卷了,讲个知识点很散的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然后用花括号括住的部分,像刻光盘一样,给你的芯片分个区,这里仅仅只是分区,不会塞东西进去。这里具体要分多少个区域,得根据芯片来,而且每个芯片的ROM和RAM区域都不一样。

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)*/

.romdata和.romzdata都是标号SECTIONS名,将iROM_0里面的.data区域分配给.romdata,.zdata区域分配给.romzdata,并且表明是ROM性质的。

__top_of_iROM_0 = MEMENDADDR(iROM_0);

将iROM_0最后的地址给到__top_of_iROM_0标号

MEMADDR(iROM_0)就是iROM_0开头地址

带嵌套例子

另一种格式也比较基础,也就是分了.sram和.heap 两个节。

.sram :

{

. = ALIGN(4);/*4字节对齐*/

*(.text.startup) /*取出.text.startup的所有的内容放在.sram里面*/

KEEP(*(.init))/*KEEP确保.init中的内容在链接过程中不会被垃圾处理法则丢弃。*/

__sram_bss_end = .;

} > int_sram /*放入上面MEMORY定义的int_sram分区当中*/

.heap (NOLOAD):

{

. += ALIGN(4);

_end = .;

end = .;

_heap_start = .;

. += HEAP_SIZE;/*将定位器.后移HEAP_SIZE长度*/

_heap_end = .;

} > int_sram

节地址

{

……

} > int_flash

. = ALIGN(4);

__text_end = .;

__sram_data_rom = __text_end;

.sram_data : AT(__sram_data_rom)

{

……

}

AT(__sram_data_rom)代表.sram_data节从__sram_data_rom的地址开始。

.DummySection : ALIGN(4)

{

……

} > Dummy

代表DummySection在前面地址对齐之后的地址开始

虚拟地址和加载地址

节里面的地址分为两种

VMA(virtual memory address虚拟内存地址)

LMA(load memory address加载内存地址)

VMA是执行输出文件时section所在的地址,而LMA是加载输出文件时section所在的地址。

通常VMA和LMA是相同的,也有不同的情况。

.sram_bss:

{

……

} > int_sram AT>int_sram

前面一个int_sram是VMA,后一个int_sram是LMA。

.sram_bss (NOLOAD) :

{

……

} > int_sram

这种就是int_sram是VMA,没有LMA。

其他带花括号的部分

这种就比较简单了,而且少见,就是最常用CONSTANTS。

CONSTANTS

{

const_data_section 0x08000000 :

{

*(.const_data) // 将程序中的只读数据放置到Flash存储器的起始地址0x08000000处

} > FLASH

}

孳的组词、含义
突尼斯足球队在世界杯上的表现如何?

友情链接