Scatter文件编写

(和《ARM嵌入式应用技术基础》186-190页一模一样)

Scatter文件编写

一个映像文件中可以包含多个域(region),在加载和运行映像文件时,每个域可以有不同的地址。每个域可以包括多达3个输出段,每个输出段是由若干个具有相同属性的输入段组成。这样在生成映像文件时,ARM链接器就需要知道下述两个信息。

  • 分组信息    决定各域中的输出段是由哪些输入段组织而成;
  • 定位信息    决定各域在存储空间中的起始地址。

根据映像文件中地址映射的复杂程度,有两种方法来告诉ARM链接器这些相关的信息。对于映像文件中地址映射关系比较简单的情况,可以使用命令行选项;对于映像文件中地址映射关系比较复杂的情况,可以使用一个scatter配置文件。Scatter文件又称为分散加载文件,将重点讲解如何编写scatter文件。

1、Scatter文件结构

Scatter文件是一个文本文件,使用BNF语法来描述ARM链接器生成映像文件时所需要的信息。具体来说,在scatter文件中可以指定下列信息:

  • 各个加载时域的加载时起始地址、最大尺寸和属性;
  • 每个加载时域包含的输出段;
  • 各个输出段的运行时起始地址、最大尺寸、存储访问特性和属性;
  • 各个输出段中包含的输入段。

一个Scatter文件包含若干个加载域,一个加载域包含若干个输出段,一个输出段由若干个具有相同属性的输入段组成,其结构如图1所示

图1 Scatter文件结构示意图

    ① 加载时域的描述

加载时域包括名称、起始地址、属性、最大尺寸和一个运行时域的列表。使用BNF语法描述,加载时域的格式如下所示:


Load_name      base_designator         attribute      max_size

{

……

}

  • Load_name   运行时域名称,它除了唯一地标识一个运行时域外,还用来构成链接器生成的链接符号;
  • base_designator 用来表示本加载时域的起始地址,它可以有两种格式表示:起始地址或偏移量;
  • attribute   本加载时域的属性,其可能的取值为下面之一,默认的取值为ABSOLUTE:
  • PI          位置无关属性;
  • RELOC       重定位;
  • ABSOLUTE    绝对地址;
  • max_size 最大尺寸,如果本加载时域的实际尺寸超过了该值,链接器将报告错误。默认的取值为0xFFFFFFFF。

    ② 输出段的描述

输出段包括名称、起始地址、属性、最大尺寸和一个输入段的集合。使用BNF语法描述,输出段的格式如下所示:


output_name     base_designator     attribute       max_size

{

……

}

  • output_name 输出段的名称,它用来唯一地标识一个输出段,还用来构成链接器生成的链接符号。
  • base_designator 用来表示本输出段的起始地址,它可以有两种格式:起始地址值或偏移量。
  • attribute   表示本输出段的属性,其可能的取值如下所示:
  • PI          位置无关属性
  • RELOC       重定位
  • ABSOLUTE    绝对地址
  • FIXED       固定地址
  • UNINIT      未初始化的数据
  • max_size    指定本输出段的最大尺寸。

    ③ 输入段的描述

输入段里描述了一个文本字符串的模式,匹配该模式的输入段都将被包含在当前域中。模式中可以使用匹配符,符号"*"代表零个或者多个字符,符号"?"代表单个字符。进行匹配时,所有字符是大小写无关的。

下面介绍一些使用scatter文件配置映像文件地址映射模式的例子。在本例中,映像文件包括一个加载时域和3个连续的输出段,这种模式适合于那些将其他程序加载到RAM中的程序,如操作系统的引导程序和Angel等。

例子    一个简单的scatter文件


Load_1   0x4000             ;定义加载时域的名称为Load_1,起始地址为0x4000

{

ER_RO    + 0     ;输出段名ER_RO,地址偏移量0,所以起始地址为0x4000

{ *( + RO) }       ;通配符*,包含了所有的RO属性的输入段,它们被连续放置

ER_RW    + 0     ;输出段名称ER_RW,起始地址为前一个输出段的结束地址加偏移量0

{ *( +  RW) }      ;本输出段包含所有的RW属性的输入段,它们被连续放置

ER_ZI 0x5000       ;输出段名称ER_ZI,起始地址为0x5000

{ *( +  ZI) }      ;本输出段包含了所有的ZI属性的输入段,它们被连续放置

}

按照例 scatter文件的描述,ARM链接器会生成相应的映像文件地址映射关系,如图2所示。

图2 程序运行时地址映射关系

2、固定时域

任何一个映像文件都需要指定一个初始入口点(initial entry point),它是影响文件运行时的入口点。初始入口点必须位于一个固定域中,所谓固定域是指该域的加载时地址和运行时地址是相同的。如果初始入口点不是位于一个固定域中,ARM链接器在链接时会产生下面的错误信息。

L6203E:Entry point (0x0000 0000) lies within non-root region 32 bit RAM

使用scatter文件时,可以有下面两种方法来设置固定域。

    ① 设置输出段地址

第1种方法是设定一个加载域中第1个输出段的运行地址,使其和该加载域的加载地址相同。这样该输出段就是一个固定域。

例1就使用这种方法确定固定域。其中,加载域LR_1的起始地址为0x8000,输出段ER_RO的起始地址指定为0x8000,与加载域LR_1的起始地址相同,因此,输出段ER_RO是一个固定域,并且是映像文件的初始入口点。

例1 指定固定域


LR_1 0x08000                ;加载域LR_1的起始地址为0x8000

{

ER_RO 0x08000          ;输出段ER_RO的起始地址为0x8000

{

*( +  RO)          ;包含了所有的RO数据,包含初始入口点

}

;其他部分内容

}

    ② 设置输出段属性

第2种方法通过将某个输出段的属性设置成FIXED。

例2指定固定域


LR_1 0x8000                 ;加载时域LR_1的起始地址为0x8000

{

ER_RO    0x8000

{

*( +  RO)          ;除了init.o之外的其他RO数据

}

ER_INIT 0x9000 FIXED   ;设置输出段属性为FIXED,确定固定域

{

init.o( +  RO)         ;本输出段包含了init.o,包含映像文件的初始入口点

}

;其他部分内容

}

3、一个实际系统的例子

在一个嵌入式设备中,为了保持好的性价比,通常在系统中存在多种存储器。在一个实际的ARM开发板中,可能包括片内Flash、RAM和片外Flash、RAM。在本例中,我们假设用ARM芯片构造了一个嵌入式系统,包含了8KB片内Flash存储器、16KB片内RAM存储器、起始地址为0x80000000的片外Flash和起始地址为0x81000000的片外RAM,其地址空间分配关系如图3所示。

在这样的ARM系统中,我们编写了程序,并且按照例3中的分散加载文件对映象文件的地址进行分配。分配后的地址映像关系如图4所示。

                                                        

图3 ARM系统中的地址空间                                                             图4 地址映像关系

从图4中可以看出:可执行代码都放在片外Flash中,并且Vectors向量表放在片外Flash的起始地址上;Startup目标文件的数据放置在片内RAM中,堆栈放在片内RAM的顶端;其他数据放置在片外RAM中,堆空间紧跟其后。

例3 片外Flash启动程序的scatter文件


ROM_LOAD  0x80000000                 ;定义加载区名称ROM_LOAD,起始地址0x80000000

{

ROM_EXE  0x80000000              ;定义执行代码空间,起始地址与加载域地址相同

{

Startup.o (vectors,  +First)     ;首先放置Startup.o文件的向量表vectors

* ( +RO)               ;后面地址空间放置其他RO属性代码

}

IRAM  0x40000000                     ;定义数据空间

{   Startup.o ( +RW, +ZI)   }

STACKS  0x40004000  UNINIT           ;定义堆栈空间

{    stack.o ( +ZI)    }

ERAM  0x81000000                     ;定义数据空间

{   * ( +RW, +ZI)      }             ;剩下未指定空间的所有数据

HEAP + 0  UNINIT                     ;定义堆空间

{     heap.o ( +ZI)    }

时间: 2024-10-08 00:42:38

Scatter文件编写的相关文章

linux库文件编写入门(笔记)

linux库文件的编写 作者: laomai地址: http://blog.csdn.net/laomai 本文主要参考了如下资料⑴hcj写的"Linux静态/动态链接库的创建和使用"地址 http://fanqiang.chinaunix.net/system/linux/2006-05-08/4126.shtml⑵雨亦奇的文章"LINUX动态链接库高级应用"地址http://www.ccw.com.cn/htm/center/prog/02_3_13_3_2.a

从简入难makefile文件编写,Linux C++编程,简单vi命令

 1.一个最基本的C++程序 2.第二个c++程序 3.第一个入门级别的简单的makefile 4.在makefile中定义变量. 5.编写makefile的依赖 如果start:标识后面的某个.o没有,则重新编译没有编译的那个文件 6.最终的makefile文件 总结:makefile是通过.o文件是否存在已经.cpp最后的修改时间来判断是否重新编译.o文件. 7.makefile不管理.h文件,它是编译器来进行管理的. vi: i在光标之前插入 a在光标后面插入 x删除后面的字符 dd删

【转】SYNOPSYS VCS Makefile文件编写与研究

原文地址:http://www.cnblogs.com/zhtxwd/archive/2012/03/30/2425180.html YNOPSYS VCS Makefile文件编写与研究 这个Makefile是synopsys提供的模板,看上去非常好用,你只要按部就班提供实际项目的参数就可以了.我们来看这个文件的头部说明: makefile 其实完全可以用csh或其他脚本来编写,只是VCS使用的linux内置的make命令定义了一个标准的仿真脚本,make命令是专门用来 做项目的源文件管理和编

OCX调用dll打成cab包时候inf文件编写

动态库:kdm_dll.dll ocx控件:UnionKdm.ocx inf文件:UnionKdm.inf 其中inf文件编写方式格式如下: [version] signature="$CHICAGO$" AdvancedINF=2.0 [DefaultInstall] CopyFiles=InstallFilesSection,InstallInfSection RegisterOCXs=RegisterOCXSection [DefaultUninstall] cleanup=1

关于keil中target配置和scatter文件的理解

下图为options for target 中target配置图及该工程文件的scatter文件. 当我们修改target中Read/Only Memory Areas 和 Read/Write Memory Areas中的地址时,编译工程文件之后,scatter文件中的地址也会自动相应改变. 观察两者之间的变化对应关系,不难发现Read/Only Memory Areas中的起始地址和大小对应的是scatter文件中的映像文件的加载地址和加载存储区域的大小: 映像文件中RO部分的加载地址等于运

简单php文件编写语法

简单php文件编写语法,老是弄错,做个笔记,经常温习下   1 <?php   2 echo "Test PHP reslove"   3 ?>   1 <?php   2 phpinfo();   3 ?>

关于Window的Dos Batch 文件编写的常识

Redirect "all" output to a single file: Run: test.bat > test.txt 2>&1 and you'll get this text on screen (we'll never get rid of this line on screen, as it is sent to the Console and cannot be redirected): This text goes to the Console

c++类模板分文件编写存在的问题

c++分文件编写的编译机制: 各个文件独立编译,如果在某.cpp文件中出现了函数调用,但是在此.cpp文件并没有对应函数的实现.此时就会在函数调用出生成特定的符号,在之后的链接过程完成函数调用. C++模板的编译机制: 模板都会进行两次编译.当编译器第一次遇到模板时进行一次普通的编译,当调用函数模板时进行第二次编译.第二次编译将特定值带入编译如: 在分文件编写类模板,不调用时.编译是不会出现问题的.如下: Car.h文件 1 #ifndef _CAR_H 2 #define _CAR_H 3 4

20150124--初始化类文件编写

和涛哥学习MVC一 目录 和涛哥学习MVC一... 1 一.项目开发流程... 2 二.MVC原理解析... 2 1.简介... 2 2.名词解析... 2 3.单一入口访问原理... 3 4.MVC单一入口原理图... 3 5.mvc项目文件结构... 3 三.编写MVC框架... 4 1.编写index.php入口文件... 4 2.编写Application.class.php初始化类文件... 4 1)初始化字符集... 4 2)初始化系统常量... 5 3)初始化错误信息... 5 4