ld: REGION_ALIAS
1
1 3.4.4 Assign alias names to memory regions
1 ------------------------------------------
1
1 Alias names can be added to existing memory regions created with the
1 ⇒MEMORY command. Each name corresponds to at most one memory
1 region.
1
1 REGION_ALIAS(ALIAS, REGION)
1
1 The 'REGION_ALIAS' function creates an alias name ALIAS for the
1 memory region REGION. This allows a flexible mapping of output sections
1 to memory regions. An example follows.
1
1 Suppose we have an application for embedded systems which come with
1 various memory storage devices. All have a general purpose, volatile
1 memory 'RAM' that allows code execution or data storage. Some may have
1 a read-only, non-volatile memory 'ROM' that allows code execution and
1 read-only data access. The last variant is a read-only, non-volatile
1 memory 'ROM2' with read-only data access and no code execution
1 capability. We have four output sections:
1
1 * '.text' program code;
1 * '.rodata' read-only data;
1 * '.data' read-write initialized data;
1 * '.bss' read-write zero initialized data.
1
1 The goal is to provide a linker command file that contains a system
1 independent part defining the output sections and a system dependent
1 part mapping the output sections to the memory regions available on the
1 system. Our embedded systems come with three different memory setups
1 'A', 'B' and 'C':
1 Section Variant A Variant B Variant C
1 .text RAM ROM ROM
1 .rodata RAM ROM ROM2
1 .data RAM RAM/ROM RAM/ROM2
1 .bss RAM RAM RAM
1 The notation 'RAM/ROM' or 'RAM/ROM2' means that this section is
1 loaded into region 'ROM' or 'ROM2' respectively. Please note that the
1 load address of the '.data' section starts in all three variants at the
1 end of the '.rodata' section.
1
1 The base linker script that deals with the output sections follows.
1 It includes the system dependent 'linkcmds.memory' file that describes
1 the memory layout:
1 INCLUDE linkcmds.memory
1
1 SECTIONS
1 {
1 .text :
1 {
1 *(.text)
1 } > REGION_TEXT
1 .rodata :
1 {
1 *(.rodata)
1 rodata_end = .;
1 } > REGION_RODATA
1 .data : AT (rodata_end)
1 {
1 data_start = .;
1 *(.data)
1 } > REGION_DATA
1 data_size = SIZEOF(.data);
1 data_load_start = LOADADDR(.data);
1 .bss :
1 {
1 *(.bss)
1 } > REGION_BSS
1 }
1
1 Now we need three different 'linkcmds.memory' files to define memory
1 regions and alias names. The content of 'linkcmds.memory' for the three
1 variants 'A', 'B' and 'C':
1 'A'
1 Here everything goes into the 'RAM'.
1 MEMORY
1 {
1 RAM : ORIGIN = 0, LENGTH = 4M
1 }
1
1 REGION_ALIAS("REGION_TEXT", RAM);
1 REGION_ALIAS("REGION_RODATA", RAM);
1 REGION_ALIAS("REGION_DATA", RAM);
1 REGION_ALIAS("REGION_BSS", RAM);
1 'B'
1 Program code and read-only data go into the 'ROM'. Read-write data
1 goes into the 'RAM'. An image of the initialized data is loaded
1 into the 'ROM' and will be copied during system start into the
1 'RAM'.
1 MEMORY
1 {
1 ROM : ORIGIN = 0, LENGTH = 3M
1 RAM : ORIGIN = 0x10000000, LENGTH = 1M
1 }
1
1 REGION_ALIAS("REGION_TEXT", ROM);
1 REGION_ALIAS("REGION_RODATA", ROM);
1 REGION_ALIAS("REGION_DATA", RAM);
1 REGION_ALIAS("REGION_BSS", RAM);
1 'C'
1 Program code goes into the 'ROM'. Read-only data goes into the
1 'ROM2'. Read-write data goes into the 'RAM'. An image of the
1 initialized data is loaded into the 'ROM2' and will be copied
1 during system start into the 'RAM'.
1 MEMORY
1 {
1 ROM : ORIGIN = 0, LENGTH = 2M
1 ROM2 : ORIGIN = 0x10000000, LENGTH = 1M
1 RAM : ORIGIN = 0x20000000, LENGTH = 1M
1 }
1
1 REGION_ALIAS("REGION_TEXT", ROM);
1 REGION_ALIAS("REGION_RODATA", ROM2);
1 REGION_ALIAS("REGION_DATA", RAM);
1 REGION_ALIAS("REGION_BSS", RAM);
1
1 It is possible to write a common system initialization routine to
1 copy the '.data' section from 'ROM' or 'ROM2' into the 'RAM' if
1 necessary:
1 #include <string.h>
1
1 extern char data_start [];
1 extern char data_size [];
1 extern char data_load_start [];
1
1 void copy_data(void)
1 {
1 if (data_start != data_load_start)
1 {
1 memcpy(data_start, data_load_start, (size_t) data_size);
1 }
1 }
1