目录
1.链接文件有什么用?
2.文件结构和语法解析
2.1 文件结构
2.2 语法解析
3.小结
玩惯了ld文件,突然让搞lsl文件,被其中花里胡哨的语法搞晕了,例如:
memory cpu0_dlmu { mau = 8; size = 64k; type = ram; map cached (dest=bus:sri, dest_offset=0x90000000, size=64k); map not_cached (dest=bus:sri, dest_offset=0xb0000000, size=64k,priority=8); }虽然这个字面意思写的很清楚,但是在链接器实际运行时有什么不一样吗,mau、priority具体表示什么?因此有必要搞一搞其底层原理。 编译原理这里就不多谈了,咱们直接从链接器开始走起。
1.链接文件有什么用?
Tasking 链接器将Linker和Locator集合到一起, Linker阶段主要把 .o文件、lib文件组合成一个可重定位的对象文件,例如.out;Locator主要用于给上述.out文件重新分配绝对地址,并生成目标处理器的文件,例如elf、hex、s19等,总体流程如下图:
在连接过程中,lsl(Linker Script Language)文件起到了非常关键的作用:
确定当前目标处理的内核硬件架构,例如逻辑地址和物理地址的偏移等;
确定当前系统的memory位置,例如RAM、ROM首地址和长度等;
确定代码数据放到memory的什么位置,这也是我们主要关心的点,控制数据代码到指定位置;
有了上述基本了解,我们来看看lsl的一些关键语法。
2.文件结构和语法解析
2.1 文件结构
lsl链接文件主要包含如下几个部分:
内核架构的定义:帮助linker将目标内核的逻辑地址转换为物理地址,可能还包括中断向量表、栈的定义等,一般来说编译器会把这个定义好,例如tc1v1_6_2.lsl;
派生的定义:主要是用于描述内部总线定义、memeory定义等;
处理器的定义:用于定义单核还是多核,以及对应内核实例
段的定义:控制自定义段的具体位置
框架如下如下:
2.2 语法解析
首先来看几个最常见到但是没有关心过的关键字,以开头代码为例:
mau:Minimal Addressable Units,最小可寻址单元,对Tricore来说就是1 byte,对应数字 8;
type:指定memory类型,常见的如rom,ram,nvram(任意时刻都可以修改),blockram
map:该关键字将源地址转为目的地址,具体映射关系如下:
space => space
space => bus
bus => bus
memory => bus
上述几个关键字接下来我们就来分析几个常用的语法。 定义memory的基本格式如下:
memory mem_name { type = xx; mau = xx; size = 64k; map map_name ( map_description ); }以定义TC3xx CPU0 DSPR的空间为例,代码如下:
memory dsram0 // Data Scratch Pad Ram { mau = 8; size=240k; type=ram; map(dest=busfpi_bus,dest_offset=0xd0000000,size=240k,priority=8); map(dest=bus:sri,dest_offset=0x70000000,size=240k); }mau = 8,表示最小寻址单位为1 byte;整块memory为240k,属于ram类型;比较好玩的是下面两块map,我们来看第一个:
map (dest=busfpi_bus, dest_offset=0xd0000000, size=240k, priority=8)目的地是Tricore 0 的FPI 总线,偏移为0xd0000000,size为240k,优先级为8;我们回过头看TC3xx的手册,会发现CH、DH这个Segment是保留的,这就奇怪了,链接文件为什么要定义这个东西?直觉告诉我这个可能和Tricore寻址方式有关系。 fpi_bus用于将CPU等连接至中低带宽外设,对应具体实例为SPB(系统外设额总线)、BBB(ADAS domain相关),位宽32bit;如下图:
map (dest=bus:sri, dest_offset=0x70000000, size=240k);那么在链接的时候,linker如何知道用0x7开头还是0xd开头的呢?根据后面的priority优先级来定。 在测试优先级的时候,上面关于DSPR的例子举的不好,因为不管我怎么调优先级都还是用的global地址,除了在调试时将某些指定到本地地址,如下:

memory cpu0_dlmu { mau = 8; size = 64k; type = ram; map cached (dest=bus:sri, dest_offset=0x90000000, size=64k); map not_cached (dest=bus:sri, dest_offset=0xb0000000, size=64k); }我们将变量放到cpu0dlmu0,在不设置优先级的情况下,编译结果如下:



section_setup ::my_space { reserved address range stack definition heap definition copy table definition start address space reference restrictions input section modifications section reference restrictions MPU data table }
group (run_addr = mem:A/map_name)修改如下:

3.小结
上面两节将lsl的基本框架和常用语法进行了梳理,其中比较重要的就是memory定义和section定义,这里最后再总结下如何将数据或者代码放到指定位置:
首先定义一块memory,使用语法memory name{ },指定map地址,mau,size;
在section_layout里用group定义运行地址,如有必要定义加载地址;
代码里在待处理的数据或者代码前后添加限定符#pragma,或者__attribute__ ((section".name"))
-
数据
+关注
关注
8文章
7222浏览量
90143 -
代码
+关注
关注
30文章
4857浏览量
69486 -
TriCore
+关注
关注
0文章
15浏览量
11801
原文标题:基于Tricore的Tasking链接文件解读
文章出处:【微信号:eng2mot,微信公众号:汽车ECU开发】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
EE-133:将ADSP-218x的传统架构文件转换为链接器描述文件

深入探讨Linux系统中的动态链接库机制

三星贴片电容的引脚结构与链接方式解析

评论