Memory Layout
The linker's default configuration permits allocation of all available memory. You can override this configuration by using the MEMORY command. The MEMORY command describes the location and size of blocks of memory in the target. By using it carefully, you can describe which memory regions may be used by the linker, and which memory regions it must avoid. The linker does not shuffle sections to fit into the available regions, but does move the requested sections into the correct regions and issue errors when the regions become too full.
A command file may contain at most one use of the MEMORY command; however, you can define as many blocks of memory within it as you wish. The syntax is:
MEMORY
{
name (attr) : ORIGIN = origin, LENGTH = len
...
}
name
is a name used internally by the linker to refer to the region. Any symbol name may be used. The region names are stored in a separate name space, and will not conflict with symbols, file names or section names. Use distinct names to specify multiple regions.
(attr)
is an optional list of attributes that specify whether to use a particular memory to place sections that are not listed in the linker script. Valid attribute lists must be made up of the characters "ALIRWX" that match section attributes. If you omit the attribute list, you may omit the parentheses around it as well. The attributes currently supported are:
`Letter'
Section Attribute
`R'
Read-only sections.
`W'
Read/write sections.
`X'
Sections containing executable code.
`A'
Allocated sections.
`I'
Initialized sections.
`L'
Same as I.
`!'
Invert the sense of any of the following attributes.
origin
is the start address of the region in physical memory. It is an expression that must evaluate to a constant before memory allocation is performed. The keyword ORIGIN may be abbreviated to org or o (but not, for example, `ORG').
len
is the size in bytes of the region (an expression). The keyword LENGTH may be abbreviated to len or l.
For example, to specify that memory has two regions available for allocation--one starting at 0 for 256 kilobytes, and the other starting at 0x40000000 for four megabytes. The rom memory region will get all sections without an explicit memory register that are either read-only or contain code, while the ram memory region will get the sections.
MEMORY
{
rom (rx) : ORIGIN = 0, LENGTH = 256K
ram (!rx) : org = 0x40000000, l = 4M
}
Once you have defined a region of memory named mem, you can direct specific output sections there by using a command ending in`>mem' within the SECTIONS command (see section Optional Section Attributes). If the combined output sections directed to a region are too big for the region, the linker will issue an error message.
/* Specify the memory areas
* 连接器在缺省状态下被配置为允许分配所有可用的内存块。你可以使用 “MEMORY”命令
* “MEMORY”命令描述目标平台上内存块的位置与长度。你可以用它来描述哪些内存区域可以被连接器使用,哪些内存区域是要避免使用的。
* 然后你就可以把节分配到特定的内存区域中。连接器会基于内存区域设置节的地址,对于太满的区域,会提示警告信息。连接器不会为了适应可用的区域而搅乱节。
* 一个连接脚本最多可以包含一次'MEMORY'命令。但是,你可以在命令中随心所欲定义任意多的内存块,语法如下:
* MEMORY
{
NAME [(ATTR)] : ORIGIN = ORIGIN, LENGTH = LEN
...
}
* NAME 是用在连接脚本中引用内存区域的名字。出了连接脚本,区域名就没有任何实际意义,区域名存储在一个单独的名字空间中,它不会和符号名、
* 文件名、节名产生冲突,每一块内存区域必须有一个唯一的名字
* ATTR 字符串是一个可选的属性列表,它指出是否为一个没有连接脚本中进行显示映射地输入段使用一个特定内存区域。如果你没有为某些输入段指定一个
* 输出段,连接器会创建一个跟输入段同名的输出段。如果你定义了区域属性,连接器会使用它们来为创建的输出段选择内存区域。
* ATTR字符串必须包含下面字符中的一个,且必须只包含一个:
* `R' 只读节。
* `W' 可读写节。
* `X' 可执行节。
* `A' 可分配节。
* `I' 已初始化节。
* `L' 同‘I’
*`!' 对前一个属性值取反。
* 如果一个未映射节匹配了上面除'!'之外的一个属性,它就会被放入该内存区域。'!'属性对该测试取反,所以
* 只有当它不匹配上面列出的行何属性时,一个未映射节才会被放入到内存区域。
* ORIGIN 是一个关于内存区域地始地址的表达式。在内存分配执行之前,这个表达式必须被求值产生一个常数,
* 这意味着你不可以使用任何节相关的符号。关键字'ORIGIN'可以被缩写为'org'或'o'(但是,不可以写为,比如‘ORG’)
* LEN 是一个关于内存区域长充(以字节为单位)的表达式。就像ORIGIN表达式,这个表达式在分配执行前也
* 必须被求得为一个常数值。关键字'LENGTH'可以被简写为‘len'或'l'。
* 在下面的例子中,我们指定两个可用于分配的内存区域:一个从0开始,有256kb长度,另一个从0x4000000
* 开始,有4mb长度。连接器会把那些没有进行显式映射且是只读或可执行的节放到'rom'内存区域。并会把另
* 外的没有被显式映射地节放入到'ram'内存区域。
MEMORY
{
rom (rx) : ORIGIN = 0, LENGTH = 256K
ram (!rx) : org = 0x40000000, l = 4M
}
* 一旦你定义了一个内存区域,你也可以指示连接器把指定的输出段放入到这个内存区域中,这可以通过使用
* '>REGION'输出段属性。比如,如果你有一个名为'mem'的内存区域,你可以在输出段定义中使用'>mem'。如
* 果没有为输出段指定地址,连接器就会把地址设置为内存区域中的下一个可用的地址。如果总共的映射到一
* 个内存区域的输出段对于区域来说太大了,连接器会提示一条错误信息。
*
*/
MEMORY
{
m_boot_data (RX) : ORIGIN = 0x60000000, LENGTH = 0x00001000
m_image_vertor_table (RX) : ORIGIN = 0x60001000, LENGTH = 0x00001000
m_interrupts (RX) : ORIGIN = 0x60002000, LENGTH = 0x00000400
m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x1F7FDC00
m_itcm (RW) : ORIGIN = 0x00000000, LENGTH = 0x00020000
m_dtcm (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000
m_ocram (RW) : ORIGIN = 0x20200000, LENGTH = 0x00040000
m_sdram (RW) : ORIGIN = 0x80000000, LENGTH = 0x01E00000
m_nocache (RW) : ORIGIN = 0x81E00000, LENGTH = 0x00200000
}