zoukankan      html  css  js  c++  java
  • 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)    }

  • 相关阅读:
    gThumb 3.1.2 发布,支持 WebP 图像
    航空例行天气预报解析 metaf2xml
    Baruwa 1.1.2 发布,邮件监控系统
    Bisect 1.3 发布,Caml 代码覆盖测试
    MoonScript 0.2.2 发布,基于 Lua 的脚本语言
    Varnish 入门
    快速增量备份程序 DeltaCopy
    恢复模糊的图像 SmartDeblur
    Cairo 1.12.8 发布,向量图形会图库
    iText 5.3.4 发布,Java 的 PDF 开发包
  • 原文地址:https://www.cnblogs.com/liuchengchuxiao/p/4171427.html
Copyright © 2011-2022 走看看