| 帮同学宣传一下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
















