分散加载文件sct

来源于网络并稍加创作:https://blog.csdn.net/u012308586/article/details/123918444

在了解keil的链接脚本之前需要了解几个重要概念:

RO(ReadOnly):表示程序中的指令和常量
RW(Read/Write):表示程序中已初始化的变量
ZI(Zero):表示程序中未初始化的变量


我们在编译keil中的工程项目时生成的目标文件时叫做镜像文件(Image)或bin文件,image文件中只包含RO,RW段,这是因为ZI数据段都是零,没有必要包含,只需要把ZI所在的区域清零即可。而其他两个数据段是被赋值了的,所以image文件需要包含已初始化变量的初值。如果我们将image文件烧录到ROM中,那么其必须包含有将RW段移动到RAM中以及将ZI段所在的地址清零的功能。这是保证烧录程序能运行起来的基本要求。
           知道基本的定义后,我们来了解链接脚本,也叫程序加载文件。在生成image文件时如何来分配相关数据的存放基址呢?这个就有链接脚本决定,如果不指定特定的链接脚本,连接器就会自动采用默认的链接脚本来生成镜像。本文主要讲解分散加载文件:分散加载文件主要由一个加载时域,多个运行时域组成。
加载时域格式如下所示:

load_region_name base_address max_size
{
     execution_region_description+
}
load_region_name为加载时域的名字,长度不超过31个字节
base_address为加载时域的起始地址,即从该地址开始加载相关代码
max_size为加载时域的最大范围,若实际大小超过该大小,链接器将会报错
execution_region_description+是对执行时域的描述
同理,运行时域格式如下:

exec_region_name base_address max_size
{
     input_section_description*
}

应用实例:

LR_IROM1 0x08020000 0x00040000 {                 ; 定义一个加载时域,域基址:0x08020000,域大
                                                                             ; 小为 0x00040000,对应实际 Flash 的大小
ER_IROM1 0x08000000 0x00040000 {                 ; 定义一个运行时域,第一个运行时域必须和加载
                                                                              ; 时域起始地址相同,否则库不能加载到该时域的
                                                                              ; 错误,其域大小一般也和加载时域大小相同
*.o (RESET, +First)                                                 ; 将 RESET 段最先加载到本域的起始地址外,即
                                                                              ; RESET 的起始地址为 0,RESET 存储的是向量表
*(InRoot$$Section)                                                           
.ANY (+RO)                                                           ; 加载所有匹配目标文件的只读属性数据,包含:
                                                                               ; Code、RW-Code、RO-Data。
.ANY (+XO)                                                          
} 
RW_IRAM1 0x20000000 0x00040000 {            ; 定义一个运行时域,域基址:0x20000000,域大
                                                                         ; 小为 0x00040000,对应实际 RAM 大小
* (+RW +ZI)                                                      ; 加载所有区配目标文件的 RW-Data、ZI-Data
                                                                          ; 这里也可以用.ANY 替代*号
}
ARM_LIB_HEP  0x20040000 EMPTY 0x70000 {            ; 定义一个运行时域,域基址:0x20040000,域大小为0x70000,预留给启动代码里的堆用
}
ARM_LIB_STACK  0x200BFFC0 EMPTY -0x BFFC0 {      ; 定义一个运行时域,域基址:0x200BFFC0,域大小为0x BFFC0,预留给启动代码里的栈用
                                                                                      ;启动代码汇编使用__
;IMPORT |Image$$ARM_LIB_STACK$$ZI$$Linit|
                                                                                 ;Vector DCD  |Image$$ARM_LIB_STACK$$ZI$$Linit| ;Top of Stack
}
BOOT_INFO  0x200BFFC0 EMPTY 0x10 {            ; 定义一个运行时域,域基址:0x200BFFC0,域大小为0 x10,预留引导信息用
			               ;C/C++使用:
               ;extern unsigned int Image$$BOOT_INFO$$ZI$$Base;//起始
               ;extern unsigned int Image$$BOOT_INFO$$ZI$$Limit; //结束
                                                                            ;#define BOOT_INFO_BASE_ADDR    ((unsigned int)(&Image$$BOOT_INFO$$ZI$$Base))//0x200BFFC0
                                                                           ;#define BOOT_INFO_END_ADDR    ((unsigned int)(&Image$$BOOT_INFO$$ZI$$Limit))//0x200BFFD0
}
MCU_SELF_TEST_RESULT  0x200BFFD0 EMPTY 0x10 {            ; 定义一个运行时域,域基址:0x200BFFD0,域大小为0 x10,预留自检信息用
}
}

sct文件的编写与使用
参考资源
1. 分散加载文件浅释.pdf。(周立功工程技术笔记)
1. DUI0377G_02_mdk_armlink_user_guide.pdf(在keil的帮助文档中可以找到)

分散加载文件.sct语法
一个分散加载文件由一个或者多个加载域(load regions)组成。每个加载域由一个或者多个执行域(execution regions)组成。执行域中又包含很多个输入段描述(Input section description)。关系图如下.

分散加载文件使用;作为注释符。

什么是加载域
加载域的组成如下:

语法格式
load_region_name (base_address | (+offset)) [attribute_list] [max_size]
{
    execution_region
}

名称(name): 加载域的名称,用户自定义。
起始地址: 本加载域的起始地址。分两种表达格式
        base_address:直接指明本加载域的起始地址。
        +offset:表示此加载域的起始地址为前一个加载域的结束地址+offset字节。offset必须字对齐。
属性(attribute_list)(可选): 用于指定加载域的特征。具体值如下
        ABSOLUTE: 绝对地址。默认属性。
        PI: 与位置无关。
        RELOC: 可重定位。
        OVERLAY: 覆盖。
        NOCOMPRESS: 不能进行压缩。
加载域大小(max_size)(可选)
        指定加载域的最大范围。默认取值0xFFFFFFFF.
一个或者多个执行域.
        执行域的组成见执行域的介绍。

什么是执行域
执行域描述了可执行文件在执行时内存(RAM+ROM)的分配。
执行域的组成类似加载域,如下:

语法格式
exec_region_name (base_address | (+offset)) [attribute_list] [max_size | Length]
{
    input section descriptions
}

名称(name): 执行域的名称,用户自定义。
起始地址: 本执行域的起始地址。分两种表达格式
        base_address:直接指明本执行域的起始地址。
        +offset:表示此执行域的起始地址为前一个执行域的结束地址+offset字节。offset必须字对齐。
属性(attribute_list)(可选): 用于指定加载域的特征。具体值如下
        ABSOLUTE: 绝对地址。默认属性。
        PI: 与位置无关。
        RELOC: 可重定位。
        OVERLAY: 覆盖。
        NOCOMPRESS: 不能进行压缩。
加载域大小(max_size)(可选)
        指定加载域的最大范围。默认取值0xFFFFFFFF.
一个或者多个输入段描述.
        输入段描述的组成见输入段描述的介绍。


什么是输入段描述
语法格式
    目标文件过滤器 [+属性]

输入段描述的组成如下:

目标文件过滤器。

  支持通配符*、?。不区分大小写。如main.o,user*.o等。可匹配的文件可以为目标文件名、库名(不带前导路径名)、库完整路径名。
        可以使用*.o匹配所有的目标文件。用*匹配所有文件,包括目标文件和库。
        可以使用.ANY进行任意的匹配。它的优先级低于*.
属性,不区分大小写:
        RO-CODE,同义词有CODE
        RO-DATA,同义词有CONST
        RO 即RO-CODE + RO-DATA,同义词有TEXT
        RW-DATA
        RW-CODE
        RW 即RW-DATA + RW-CODE,同义词有DATA
        ZI,同义词有BSS
        ENTRY 即包含ENTRY的段。
        FIRST
        LAST
example:
        *.o (RESET, +First) 任何目标文件中的RESET段放在起始位置。
        .ANY (+RW +ZI)匹配任意文件的数据段。
        .ANY (+RO) 匹配任意文件的代码段。

  • 19
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值