帮同学宣传一下http://shop57644665.taobao.com/

直接通过一个例子来解释。
-c /* Autoinitialize variables at runtime */
在代码中可以使用scatter file中的符号。

以下这个MEMORY字段是这个系统的整体上划分。包括系统的flash,片外ram,片内ram,还有也表明了已经固化的ROM的地址及其长度。

MEMORY
{
/* Secure Boot ROM */
BOOT_MEM (RXI)  : org = 0×00000000   len = 0×00100000
名称(属性) 要固定的起始地址  长度。
/* CS0: External SRAM 2 Mbytes */
D_MEM0   (RW)  : org = 0×00400000   len = 0×002d0000

/* code Area */
P_MEM0   (RXI) : org = 0×06000000   len = 0×00210000
P_MEM1   (RXI) : org = 0×06210000   len = 0×001f0000
P_MEM2   (RXI) : org = 0×06400000   len = 0×00080000
P_MEM3   (RXI) : org = 0×06480000   len = 0×00180000

/* resource Area */
R_MEM      (RXI)  : org = 0×06600000   len = 0×00200000

/* FFS Area  */
FFS_MEM  (RI)  : org = 0×06800000   len = 0×00800000

S_ROM   (RXI) : org = 0×08050000   len = 0×00030000

/* Allocate memory for MIDI and JPEG */

/* CS6: Calypso+ Internal SRAM 320 kbytes */
/* Code & Variables Memory */
S_MEM    (RXW) : org = 0×08000000   len = 0×00037560 /*0×0004FB60*/
}

-heap 0×10000    /*HEAP AREA SIZE*/
Heap是留给系统实时库使用的空间。

SECTIONS字段是对MEMORY中各个段的详细描述。

SECTIONS
{
/* Entry point of the Firmware */
.start   : {} > 0×06000000
.start是使用预处理指定定义的一个标识,代码中是
.sect “.start”
这里将其地址固定在0×06000000处。

/*
*  Interrupt vector re-mapping management
*/
.intload : {} > 0×06000004
.indint  : {} load = 0×06000008, run = 0×0800000C
.indint的代码储存在flash中的地址也就是load的地址是0×06000008,但是可以通过run = 0×0800000C来实现其在ram运行,在ram中的地址是0×0800000C,链接器在link时对该处使用在ram中的地址来进行链接。

.inttext : {} > P_MEM0     /* int.s Code */

.bss_dar : > D_MEM0        /* DAR SWE Variables */
{
$(BSS_DAR_LIB)
}
名称为BSS_DAR_LIB的lib的bss,也就是全局变量放入到D_MEM0,而且他们有一个标识.bss_dar
.bss     : > D_MEM0        /* Global & Static Variables */
{
$(BSS_BOOT_LIB)
}
.bss是编译器默认的全局变量的名称。以上一段是将名称为BSS_BOOT_LIB的lib中的全局变量放入到D_MEM0中。

以下这个组是用来将一些全局变量放入到片内ram S_MEM中而不是放到片外的D_MEM0中。
GROUP
{
S_D_Mem /* Label of start address of .bss section in Int. RAM */
S_D_Mem是一个标志变量,作为开始的一个标志。后面的E_D_Mem作为该段的一个结束标志。
这个标志是这样添加的。
#pragma DATA_SECTION(d_application_run_start,”S_P_Mem”)
const UWORD32 d_application_run_start = 0L;

.DintMem
{

/*
* .bss sections of the application
*/

$(BSS_LIBS)

}
E_D_Mem /* Label of end address of .bss section in Int. RAM */
} > S_MEM

/*
* .text and .const sections which must be mapped in internal RAM.
*/
以下是实现将一些函数放入片内ram中执行的部分。依然使用load run实现,同时为了定位要放入的部分,依然使用了前后标志来进行定位。
.ldfl  : {} > P_MEM2 /* Used to know the start load address */
GROUP load = P_MEM2, run = 0×08000044
{
S_P_Mem  /* Label of start address of .text & .const sections in Int. RAM */
.PIntMem
{
/*
* .text and .const sections of the application.

*/

$(CONST_LIBS)

}
/* Add for EMIFS changes into internal RAM  */
.emifconf
E_P_Mem /* Label of end address of .text and .const sections in Int. RAM */
}
当以上定义好以后,再在系统boot是调用代码将flash中的代码手动copy到片内ram中。Copy步骤当然是必须的,因为这部分的代码虽然link的地址是片内ram但是却是存放在flash中的,刚上电时片内ram中是没有对应的代码的,所以必须手动copy。
/*
* The rest of the code is mapped in flash, however the trampolines
* load address should be consistent with .text.
*/
这个是一个注释的例子。
COMMENT2START
`trampolines load = P_MEM2 , run = S_MEM
COMMENT2END

.text    : {} >>   P_MEM0 | P_MEM1| P_MEM2 | P_MEM3  /* Code */
.text是编译器默认的代码名称。
/*
* The rest of the constants is mapped in flash.
*/

.cinit   : {} >   P_MEM3  /* Initialization Tables */

.const   : {} >>  P_MEM3 | P_MEM1   /* Constant Data */
.HISR_stack: {} > S_MEM

.stackandheap :> S_MEM   /* System Stacks, etc… */
{
/* Leave 20 32bit words for register pushes. */
. = align(8);
. += 20 * 4;

/* Stack for abort and/or undefined modes. */
exception_stack = .;

/* Leave 38 32bit words for state saving on exceptions. */
/*  _xdump_buffer = .;
. += 38 * 4;
. = align(8);
*/
/* Beginning of stacks and heap area - 2.75 kbytes (int.s) */
stack_segment = .;
. += 0xB00;
}

.data    : {} > D_MEM0     /* Initialized Data */
.data是编译器默认的已经初始化值的全局变量。
}
对于生成的符号在程序中的使用如下例子。
.global exception_stack        ; top address of SVC mode stack
ldr     r13,Exception_Stack     ;
Exception_Stack
.word   exception_stack