CMD File
Table of Contents
三部分组成:
- 输入/输出定义:这一部分,可 以通过ccs的“Build Option……..”菜单设置 .obj 链接的目标文件 .lib 链接的库文件 .map 生成的交叉索引文件 .out 生成的可执行代码
- MEMORY命令:描述系统实际的硬件资源
- SECTION命 令:描述“段”如何定
File Reference
- Linker CMD Files for CCS http://processors.wiki.ti.com/index.php/Linker_CMD_Files_for_CCS
- TMS320C6000 Assembly Language Tools Chapter5: Linking C/C++ Code
- TMS320C6000 Optimizing Compiler v 7.3 Chapter7: Linker Description
- CMD文件配置详解
Linker Overview
Two powerful directives, MEMORY and SECTIONS, allow you to:
• Allocate sections into specific areas of memory • Combine object file sections • Define or redefine global symbols at link time
Linker Options
--heap_size
-heap
Sets heap size (for the dynamic memory allocation in C) to size bytes and defines a global symbol that specifies the heap size. Default = 1K bytes. Section 7.4.111--stack_size
-stack
Sets C system stack size to size bytes and defines a global symbol that specifies the stack size. Default = 1K bytes. Section 7.4.261
Wild Cards in File, Section, and Symbol Patterns
The linker allows file, section, and symbol names to be specified using the asterisk (*) and question mark (?) wild cards. Using * matches any number of characters and using ? matches a single character.
Define Heap Size (--heap_size
Option)
The C/C++ compiler uses an uninitialized section called .sysmem
for
the C run-time memory pool used by malloc()
. You can set the size of
this memory pool at link time by using the –heapsize option. The
syntax for the –heapsize option is:
--heap_size= size
The size must be a constant. This example defines a 4K byte heap:
cl6x --run_linker --heap_size=0x1000 /* defines a 4k heap (.sysmem section)*/
The linker creates the .sysmem
section only if there is a .sysmem section in an input file.
The linker also creates a global symbol _SYSMEMSIZE and assigns it a
value equal to the size of the heap. The default size is 1K bytes.
Define Stack Size (--stack_size
Option)
The TMS320C6000 C/C++ compiler uses an uninitialized section,
.stack
, to allocate space for the run-time stack. The syntax for the
--stack_size
option is:
--stack_size= size
The size must be a constant and is in bytes. This example defines a 4K byte stack:
cl6x --run_linker --stack_size=0x1000 /* defines a 4K heap (.stack section)*/
When the linker defines the .stack section, it also defines a global
symbol, __STACK_SIZE
, and assigns it a value equal to the size of the
section. The default software stack size is 1K bytes.
Constants in Linker Command Files
The MEMORY Directive
The linker determines where output sections are allocated into memory; it must have a model of target memory to accomplish this. The MEMORY directive allows you to specify a model of target memory so that you can define the types of memory your system contains and the address ranges they occupy.
After you use MEMORY to define a memory model, you can use the SECTIONS directive to allocate output sections into defined memory.
- MEMORY Directive Syntax
The MEMORY directive in Example defines a system that has 4K bytes of fast external memory at address 0x0000 0000, 2K bytes of slow external memory at address 0x0000 1000 and 4K bytes of slow external memory at address 0x1000 0000. It also demonstrates the use of memory range expressions as well as start/end/size address operators
Example
/********************************************************/ /* Sample command file with MEMORY directive */ /********************************************************/ file1.obj file2.obj /* Input files */ --output_file=prog.out /* Options */ #define BUFFER 0 MEMORY { FAST_MEM (RX): origin = 0x00000000 length = 0x00001000 + BUFFER SLOW_MEM (RW): origin = end(FAST_MEM) length = 0x00001800 - size(FAST_MEM) EXT_MEM (RX): origin = 0x10000000 length = size(FAST_MEM) }
The general syntax for the MEMORY directive is:
MEMORY { name 1 [( attr )] : origin = expression , length = expression [, fill = constant] . . name n [( attr )] : origin = expression , length = expression [, fill = constant] }
- attr R specifies that the memory can be read. W specifies that the memory can be written to. X specifies that the memory can contain executable code. I specifies that the memory can be initialized.
- origin specifies the starting address of a memory range; enter as origin, org, or o. The value, specified in bytes, is an expression of 32-bit constants, which can be decimal, octal, or hexadecimal.
- length specifies the length of a memory range; enter as length, len, or l. The value, specified in bytes, is an expression of 32-bit constants,
- fill specifies a fill character for the memory range; enter as fill or f. Fills are optional. The value is a integer constant and can be decimal, octal, or hexadecimal. The fill value is used to fill areas of the memory range that are not allocated to a section
Filling Memory Ranges: If you specify fill values for large memory ranges, your output file will be very large because filling a memory range (even with 0s) causes raw data to be generated for all unallocated blocks of memory in the range.
Example The following example specifies a memory range with the R and W attributes and a fill constant of 0FFFFFFFFh
MEMORY { RFILE (RW) : o = 0x00000020, l = 0x00001000, f = 0xFFFFFFFF }
- Expressions and Address Operators
Three new address operators have been added for referencing memory range properties from prior memory range entries:
- START(MR) Returns start address for previously defined memory range MR.
- SIZE(MR) Returns size of previously defined memory range MR.
- END(MR) Returns end address for previously defined memory range MR. Example
/********************************************************/ /* Sample command file with MEMORY directive */ /********************************************************/ file1.obj file2.obj /* Input files */ --output_file=prog.out /* Options */ #define ORIGIN 0x00000000 #define BUFFER 0x00000200 #define CACHE 0x0001000 MEMORY { FAST_MEM (RX): origin = ORIGIN + CACHE length = 0x00001000 + BUFFER SLOW_MEM (RW): origin = end(FAST_MEM) length = 0x00001800 - size(FAST_MEM) EXT_MEM (RX): origin = 0x10000000 length = size(FAST_MEM) - CACHE }
The SECTIONS Directive
- SECTIONS Directive Syntax
SECTIONS { name : [property [, property] [, property] . . . ] name : [property [, property] [, property] . . . ] name : [property [, property] [, property] . . . ] }
Possible properties for a section are as follows:
- Load allocation defines where in memory the section is to be loaded. Syntax: load = allocation or allocation or > allocation
- Run allocation defines where in memory the section is to be run. Syntax: run = allocation or run > allocation
- Input sections defines the input sections (object files) that constitute the output section. Syntax: { inputsections }
- Section type defines flags for special section types. Syntax: type = COPY or type = DSECT or type = NOLOAD
- Fill value defines the value used to fill uninitialized holes. Syntax: fill = value or name : [properties = value]
- Allocation
- Binding allocates a section at a specific address.
.text: load = 0x1000
- Named memory allocates the section into a range defined in the MEMORY directive with the specified
name (like SLOWMEM) or attributes.
.text: load > SLOW_MEM
- Alignment uses the align or palign keyword to specify that the
section must start on an address boundary.
.text: align = 0x100
- Blocking uses the block keyword to specify that the section must fit
between two address boundaries: if the section is too big, it starts on an address boundary.
.text: block(0x100)
- Binding allocates a section at a specific address.
- Symbols Defined by the Linker
- .text is assigned the first address of the .text output section. (It marks the beginning of executable code.)
- etext is assigned the first address following the .text output section. (It marks the end of executable code.)
- .data is assigned the first address of the .data output section. (It marks the beginning of initialized data tables.)
- edata is assigned the first address following the .data output section. (It marks the end of initialized data tables.)
- .bss is assigned the first address of the .bss output section. (It marks the beginning of uninitialized data.)
- end is assigned the first address following the .bss output section. (It marks the end of uninitialized data.)
Default Allocation Algorithm
If you do not use the MEMORY and SECTIONS directives, the linker allocates output sections as though the definitions in Example were specified. Example Default Allocation for TMS320C6000 Devices
MEMORY { RAM : origin = 0x00000001, length = 0xFFFFFFFE } SECTIONS { .text : ALIGN(32) {} > RAM .const : ALIGN(8) {} > RAM .data : ALIGN(8) {} > RAM .bss : ALIGN(8) {} > RAM .cinit : ALIGN(4) {} > RAM ; cflag option only .pinit : ALIGN(4) {} > RAM ; cflag option only .stack : ALIGN(8) {} > RAM ; cflag option only .far : ALIGN(8) {} > RAM ; cflag option only .sysmem: ALIGN(8) {} > RAM ; cflag option only .switch: ALIGN(4) {} > RAM ; cflag option only .cio : ALIGN(4) {} > RAM ; cflag option only }
Linking C/C++ Code
Run-Time Initialization
C/C++ programs require initialization of the run-time environment before execution of the program itself may begin. This initialization is performed by a bootstrap routine. This routine is responsible for creating the stack, initializing global variables, and calling main(). The bootstrap routine should be the entry point for the program, and it typically should be the RESET interrupt handler. The bootstrap routine is responsible for the following tasks:
- Set up the stack by initializing SP
- Set up the data page pointer DP (for architectures that have one)
- Set configuration registers
- Process the .cinit table to autoinitialize global variables (when using the –rommodel option)
- Process the .pinit table to construct global C++ objects.
- Call main with appropriate arguments
- Call exit when main returns
Specifying Where to Allocate Sections in Memory
(1)被初始化的“SECTIONS”(包括数据表和可执行代码)
- .text 它包括所有的可执行代码和常数,必须放在程序页;
- .cinit 它包括初始化的变量和常量表,要求放在程序页;
- .pinit 它包括全局构造器(C++)初始化的变量和常量表,要求放在程序页;
- .const 它包括字符串、声明、以及被明确初始化过的全局和静态变量,要求放在低地址的数 据页;
- .econst 它是在使用大存储器模式时使用的,包括字符串、声明、以及被明确初始化过的全 局变量和静态变量,可以放在数据页的任何地方。
- .switch 它包括为转换声明设置的表格,可以放在程序页也可以放在低地址的数据页。
(2)未被初始化的“SECTIONS”(为程序运行中创建和存放的变量在存储器中保留空间)
- .bss 它为全局变量和静态变量保留空间。在程序开始运行时,C 导入路径把数据从.cinit 节复 制出去然后存在.bss节中,要求放在低地址的数据页;
- .ebss 它是在远(far)访问(只用于 C)和大存储模式下使用,它为全局变量和静态变量保留空间。 在程序开始运行时,C 导入路径把数据从.cinit 段复制出去然后存在.ebss 节中,可以放在数据页的任何地方;
- .stack为C系统堆栈保留空间,这部分存储器为用来将声明传给函数及为局部变量留出空间, 要求放在低地址的数据页;
- .system 动态存储器分配保留空间。这个空间用于 malloc 函数,如果不使用 malloc 函数,这个段的大小就是 0,要求放在低地址的数据页;
- .esystem 动态存储器分配保留空间,这个空间用于外部 malloc 函数,如果不使用外部 malloc函数,这个段的大小就是 0,可以放在数据页的任何地方
Table 5-1 summarizes the initialized sections created under the COFF ABI mode. Table 5-2 summarizes the initialized sections created under the EABI mode. Table 5-3 summarizes the uninitialized sections. Be aware that the COFF ABI .cinit and .pinit (.initarray in EABI) tables have different formats in EABI.
Table 5-1. Initialized Sections Created by the Compiler for COFFABI Name Contents
.args
Command argument for host-based loader; read-only (see the –argsize option).cinit
Tables for explicitly initialized global and static variables- .const Global and static const variables that are explicitly initialized and contain string literals
- .pinit Table of constructors to be called at startup
- .ppdata Data tables for compiler-based profiling (see the –genprofileinfo option)
- .ppinfo Correlation tables for compiler-based profiling ( see the –genprofileinfo option)
- .switch Jump tables for large switch statements
- .text Executable code and constants
Table 5-2. Initialized Sections Created by the Compiler for EABI
Name Contents
- .args Command argument for host-based loader; read-only (see the –argsize option)
- .binit Boot time copy tables (See the TMS320C6000 Assembly Language Tools User's Guide for information on BINIT in linker command files.)
- .cinit In EABI mode, the compiler does not generate a .cinit section. However, when the –rommode linker option is specified, the linker creates this section, which contains tables for explicitly initialized global and static variables.
- .const Far, const global and static variables, and string constants
- .c6xabi.exidx Index table for exception handling; read-only (see –exceptions option)
- .c6xabi.extab Unwinded instructions for exception handling; read-only (see –exceptions option)
- .fardata Far non-const global and static variables that are explicitly initialized
- .initarray Table of constructors to be called at startup
- .name.load Compressed image of section name; read-only (See the TMS320C6000 Assembly Language Tools User's Guide for information on copy tables.)
- .neardata Near non-const global and static variables that are explicitly initialized
- .ppdata Data tables for compiler-based profiling (see the –genprofileinfo option)
- .ppinfo Correlation tables for compiler-based profiling (see the –genprofileinfo option)
- .rodata Global and static variables that have near and const qualifiers
- .switch Jump tables for large switch statements
- .text Executable code and constants
Table 5-3. Uninitialized Sections Created by the Compiler for Both ABIs
Name Contents
- .bss Global and static variables
- .far Global and static variables declared far
- .stack Stack
- .sysmem Memory for malloc functions (heap)
When you link your program, you must specify where to allocate the sections in memory. In general, initialized sections are linked into ROM or RAM; uninitialized sections are linked into RAM. With the exception of code sections, the initialized and uninitialized sections created by the compiler cannot be allocated into internal program memory
A Sample Linker Command File
Example 5-2 shows a typical linker command file that links a C program. The command file in this example is named lnk.cmd and lists several linker options:
- –rommodel Tells the linker to use autoinitialization at run time.
- –heapsize Tells the linker to set the C heap size at 0x2000 bytes.
- –stacksize Tells the linker to set the stack size to 0x0100 bytes.
- –library Tells the linker to use an archive library file, rts6200.lib, for input. Example 5-2. Linker Command File
--rom_model --heap_size=0x2000 --stack_size=0x0100 --library=rts6200.lib MEMORY { VECS: o = 0x00000000 l = 0x000000400 /* reset & interrupt vectors */ PMEM: o = 0x00000400 l = 0x00000FC00 /* intended for initialization */ BMEM: o = 0x80000000 l = 0x000010000 /* .bss, .sysmem, .stack, .cinit */ } SECTIONS { vectors > VECS .text > PMEM .data > BMEM .stack > BMEM .bss > BMEM .sysmem > BMEM .cinit > BMEM .const > BMEM .cio > BMEM .far > BMEM }
More example for reference
Exmaple 1
-stack 0x00004000 /* Stack Size */ -heap 0x00004000 /* Heap Size */ MEMORY { VECS: o = 0x402F0000 l = 0x00000080 ARMRAM: o = 0x402F0080 l = 0x0000FF80 /* 64 kBytes */ OCMCSRAM0: o = 0x40300000 l = 0x00040000 /* 256 kBytes */ OCMCSRAM1: o = 0x40400000 l = 0x00040000 /* 256 kBytes */ DDR3_0: o = 0x80000000 l = 0x20000000 /* 512 MBytes */ DDR3_1: o = 0xC0000000 l = 0x20000000 /* 512 MBytes */ } SECTIONS { .bss > OCMCSRAM0 .cinit > OCMCSRAM0 .cio > OCMCSRAM0 .const > OCMCSRAM0 .stack > OCMCSRAM1 .sysmem > OCMCSRAM0 .text > OCMCSRAM0 .ddr2 > OCMCSRAM0 }
Exmaple 2(C6A816x.cmd)
-heap 0x2000 -stack 0x2000 MEMORY { DSPL2 o = 0x00800000 l = 0x00040000 /* 256kB DSP L2 RAM */ DSPL1P o = 0x00E00000 l = 0x00008000 /* 32kB DSP L1 Program Cache/RAM */ DSPL1D o = 0x00F00000 l = 0x00008000 /* 32kB DSP L1 Data Cache/RAM */ L3OCMC0 o = 0x40300000 l = 0x00040000 /* 256kB L3 OCMC SRAM */ L3OCMC1 o = 0x40400000 l = 0x00040000 /* 256kB L3 OCMC SRAM */ SHDSPL2 o = 0x40800000 l = 0x00040000 /* 256kB Shared DSP L2 RAM */ SHDSPL1P o = 0x40E00000 l = 0x00008000 /* 32kB Shared DSP L1 Program Cache/RAM */ SHDSPL1D o = 0x40F00000 l = 0x00008000 /* 32kB Shared DSP L1 Data Cache/RAM */ DDR0 o = 0x80000000 l = 0x40000000 /* 1GB external DDR Bank 0 */ DDR1 o = 0xC0000000 l = 0x40000000 /* 1GB external DDR Bank 1 */ } SECTIONS { .text > DDR0 .stack > DDR0 .bss > DDR0 .cio > DDR0 .const > DDR0 .data > DDR0 .switch > DDR0 .sysmem > DDR0 .far > DDR0 .args > DDR0 .ppinfo > DDR0 .ppdata > DDR0 /* TI-ABI or COFF sections */ .pinit > DDR0 .cinit > DDR0 /* EABI sections */ .binit > DDR0 .init_array > DDR0 .neardata > DDR0 .fardata > DDR0 .rodata > DDR0 .c6xabi.exidx > DDR0 .c6xabi.extab > DDR0 }
Exmaple 3(C6747.cmd)
-stack 0x2000 -heap 0x4000 MEMORY { DSPL2ROM o = 0x00700000 l = 0x00010000 /* 1MB L2 Internal ROM */ DSPL2RAM o = 0x00800000 l = 0x00040000 /* 256kB L2 Internal RAM */ DSPL1PRAM o = 0x00E00000 l = 0x00008000 /* 32kB L1 Internal Program RAM */ DSPL1DRAM o = 0x00F00000 l = 0x00008000 /* 32kB L1 Internal Data RAM */ SHDSPL2ROM o = 0x11700000 l = 0x00100000 /* 1MB L2 Shared Internal ROM */ SHDSPL2RAM o = 0x11800000 l = 0x00040000 /* 256kB L2 Shared Internal RAM */ SHDSPL1PRAM o = 0x11E00000 l = 0x00008000 /* 32kB L1 Shared Internal Program RAM */ SHDSPL1DRAM o = 0x11F00000 l = 0x00008000 /* 32kB L1 Shared Internal Data RAM */ EMIFASDRAM o = 0x40000000 l = 0x08000000 /* 64MB SDRAM Data (CS0) */ EMIFACS2 o = 0x60000000 l = 0x02000000 /* 32MB Async Data (CS2) */ EMIFACS3 o = 0x62000000 l = 0x02000000 /* 32MB Async Data (CS3) */ EMIFACS4 o = 0x64000000 l = 0x02000000 /* 32MB Async Data (CS4) */ EMIFACS5 o = 0x66000000 l = 0x02000000 /* 32MB Async Data (CS5) */ SHRAM o = 0x80000000 l = 0x00020000 /* 128kB Shared RAM */ EMIFBSDRAM o = 0xC0000000 l = 0x10000000 /* 256MB SDRAM Data */ } SECTIONS { .text > SHRAM .stack > SHRAM .bss > SHRAM .cio > SHRAM .const > SHRAM .data > SHRAM .switch > SHRAM .sysmem > SHRAM .far > SHRAM .args > SHRAM .ppinfo > SHRAM .ppdata > SHRAM /* COFF sections */ .pinit > SHRAM .cinit > SHRAM /* EABI sections */ .binit > SHRAM .init_array > SHRAM .neardata > SHRAM .fardata > SHRAM .rodata > SHRAM .c6xabi.exidx > SHRAM .c6xabi.extab > SHRAM }
Footnotes:
TMS320C6000 Assembly Language Tools