Scatter文件的编写、分析

news/2024/11/17 22:41:04/

ARM编程:Scatter文件的编写、分析2009-03-19 18:10今天拿了被同事扔一边的ARM培训资料翻阅,读至scatter一节,发现写得甚是精辟。之前看的很多国人写得文章,未免有简单问题复杂化之嫌。而ARM的RVCT手册又偏冗长,不易让人立刻看到重点。今归纳如下:

 

scatter基本点:

1. 编译后输出的映像文件中各段是首尾相连的,中间没有空闲的区域,它们的先后关系是根据链接时参数的先后次序决定的 armlinker -file1.o file2.o ……

2. scatter用于将编译后的映像文件中的特定段加载到多个分散的指定内存区域

3. 有2类域region:执行域(execution region,一般是ram区域)和加载域(load region,一般是rom区域)

4. 加载域:就是编译之后得到的二进制文件烧写到rom中的这一段区域,所有的代码RO、预定义变量RW、堆栈之类清不清空无关紧要的大片内存区域ZI,都包括在其中

5. 执行域:就是把加载域进行‘解压缩’后的样子。比如:RO没有变动还是在ROM中,RW被移到了SRAM中,而ZI被放置在SDRAM中

6. scatter本身并不能对映像实现‘解压缩’,编译器读入scatter文件之后会根据其中的各种地址生成启动代码,实现对映像的加载,而这一段代码就是* (InRoot$$Sections)它是__main()的一部分。这就是在汇编启动代码的最后跳转到__main() 而不是跳向main()的原因之一。

7. 起始地址与加载域重合的执行域成为root region,* (InRoot$$Sections)必须放在这个执行域中,否则链接的时候会报错。*(+RO)包含了* (InRoot$$Sections),所以如果在root region中用到了*(+RO)可以不再指定* (InRoot$$Sections),

 

scatter语法:

ROM_LOAD 0x00000000

{

     ROM 0x00000000 0x003FFFFF       

    { 

       vectors.o (+RO,+FIRST)

      * (InRoot$$Sections)       ; All library sections that must be in a root region

      *(+RO)

    }

 

     SRAM 0x00400000 0x003FFFFF

    {

        * (+RW,+ZI)

    }

 

    SDRAM1 0x41000000 UNINIT

    { 

         stack.o (+ZI) ; stack.s中定义了top_of_stack为长度为1的space,指定栈顶地址

    }  

 

    SDRAM2 +0 UNINIT

    {    

        heap.o (+ZI)

    }

 

 

}

 

注解:

1. ROM_LOAD是加载域。这里只有一个,也可以有多个(rom地址不连续的情况)

2. ROM、SRAM、SDRAM1、SDRAM2是执行域,有多个。第一个执行域必须和加载域地址重合,因为ARM的复位地址就是加载域的起始地址(有bootstrap的话加载域址就是bootstrap执行完后的跳转地址)

3. vectors.o (+RO, +FIRST) 中断向量表放在最开头

4. ROM 0x00000000 0x003FFFFF; 加载域名 起始地址 最大允许长度;‘最大允许长度’也可以省略,但缺点是编译器不会检查段是否溢出和别的段重叠了。‘起始地址’= +0表示紧接着上一段开始的连续地址。

5. * (InRoot$$Sections)是复制代码的代码

6. UNINT关键字表示不进行初始化清零

 

 

值得注意的是:在一个scatter文件中,同一个.o文件不能出现2次,即使是在2个不同的加载域中也不可以,否则会报错:Ambiguous selectors found for *.o,错误的例子:

 

LOAD1 0x00000000

{

    EXE1

    {

            Init.o

     }

}

 

LOAD2 0xFFFF0000

{

    EXE2

    {

            Init.o

     }

}

 

想起了中学里哲学课上老师让解释为什么人不能两次踏入同一条河流,当年稀里糊涂的写的答案,老师批了个大差,回去有没有补上,今天居然在这里遇到了老问题。。。推测是编译器自动生成的scatter载入代码InRoot$$Sections不支持把同一obj搬移2次。

这就带来一个问题:如果希望把同一段代码(如中断跳转表)载入2份拷贝到不同的地址,咋整?一个笨办法是自己写一段代码搬移程序来代替编译器自动生成的搬移代码,但前提是需要搞懂映像文件的组织,增加了工作量。投机一点的方法是在makefile中把一个.o文件复制并重新起一个名字,然后把它们传递给armlink。另外,猜测scatter语法可能包含诸如+duplicate之类的关键字来允许同一段的多个副本,懒得翻ARM手册,请哪位知情者留言告知,

 

 

150XN02 

//yy-iv150401

LM190E08

G170EG01

12.1LG55


http://www.ppmy.cn/news/749975.html

相关文章

3D中的常用材质的调整方法

一、木纹材质调整方法 1. 木纹材质的肌理调整: A.使用过度色通道贴图后加入凹凸通道贴图,使木纹有凹凸感,肌理更明显凹凸通道强度通常为30% B.材质球的高光强度(specular level:)…

C++高级用法简单应用及docker的使用技巧

//std::move的移动构造函数的简单使用; #include using namespace std; int main() { std::string str(“hello”); std::vectorstd::string strvec; strvec.push_back(str); cout<<str<<endl; strvec.push_back(std::move(str)); //调用std::move移动构造函数&a…

Hadoop2.6分布式 automatic HA+Federation+Yarn教程

一、前言 与Hadoop1.x相比&#xff0c;Hadoop2.x中的NameNode不再是只有一个了&#xff0c;可以有多个&#xff08;目前只支持2个&#xff09;。每一个都有相同的职能。 这两个NameNode的地位如何哪&#xff1f; 答&#xff1a;一个是active状态的&#xff0c;一个是standby…

katago安装使用

看了今天柯洁和大申的比赛, AI还是太强了 本文介绍的是windows下如何配置 项目下载地址: https://github.com/lightvector/KataGo/releases 有显卡的推荐opencl版本, 作者推荐理由 OpenCL vs CUDA vs Eigen KataGo has three backends, OpenCL (GPU), CUDA (GPU), and Eigen…

围棋AI-KataGo安装记录

KataGo 项目地址: https://github.com/lightvector/KataGo/releases 计算平台选择 最新版本为 v1.8.2 有三种版本: OpenCL vs CUDA vs Eigen 项目说明中的描述如下 KataGo has three backends, OpenCL (GPU), CUDA (GPU), and Eigen (CPU). The quick summary is: Use Open…

java实现字符压缩算法

public class CompressionAlgorithm1 { /** * param args * 实现简易字符串压缩算法&#xff1a;一个长度最大为128的字符串&#xff0c; * 由字母a-z或者A-Z组成&#xff0c;将其中连续出现2次以上&#xff08;含2次&#xff09;的字母转换为字母和出现次数&#xff0c; * 以达…

oracle job调用shell,Oralce通过Java调用Shell 无响应解决方法

Oralce通过Java调用Shell 无响应 本帖最后由 loomz 于 2014-02-25 18:52:24 编辑 各位好&#xff1a; 我目前在做一个程序&#xff0c;Oracle存储过程通过Java(Java Sources)调用Shell脚本&#xff0c;试好其它方法&#xff0c;都没有成功。下面是我用通过java调用shell的代码&…

C++写的12306抢票软件

写在前面的话 每年逢年过节&#xff0c;一票难求读者肯定不陌生。这篇文章&#xff0c;我们带领读者从零实现一款12306刷票软件&#xff0c;其核心原理还是通过发送http请求模拟登录12306网站的购票的过程&#xff0c;最后买到票。 郑重申明一下&#xff1a;这里介绍的技术仅供…