Next: Miscellaneous Commands, Previous: Format Commands, Up: Simple Commands

#### 3.4.4 Assign alias names to memory regions

Alias names can be added to existing memory regions created with the MEMORY command. Each name corresponds to at most one memory region.

         REGION_ALIAS(alias, region)

The `REGION_ALIAS` function creates an alias name alias for the memory region region. This allows a flexible mapping of output sections to memory regions. An example follows.

Suppose we have an application for embedded systems which come with various memory storage devices. All have a general purpose, volatile memory `RAM` that allows code execution or data storage. Some may have a read-only, non-volatile memory `ROM` that allows code execution and read-only data access. The last variant is a read-only, non-volatile memory `ROM2` with read-only data access and no code execution capability. We have four output sections:

- `.text` program code;
- `.rodata` read-only data;
- `.data` read-write initialized data;
- `.bss` read-write zero initialized data.

The goal is to provide a linker command file that contains a system independent part defining the output sections and a system dependent part mapping the output sections to the memory regions available on the system. Our embedded systems come with three different memory setups `A`, `B` and `C`:

Section | Variant A | Variant B | Variant C
.text | RAM | ROM | ROM
.rodata | RAM | ROM | ROM2
.data | RAM | RAM/ROM | RAM/ROM2
.bss | RAM | RAM | RAM

The notation `RAM/ROM` or `RAM/ROM2` means that this section is loaded into region `ROM` or `ROM2` respectively. Please note that the load address of the `.data` section starts in all three variants at the end of the `.rodata` section.

The base linker script that deals with the output sections follows. It includes the system dependent `linkcmds.memory` file that describes the memory layout:

         INCLUDE linkcmds.memory

         SECTIONS
           {
             .text :
               {
                 *(.text)
               } > REGION_TEXT
             .rodata :
               {
                 *(.rodata)
                 rodata_end = .;
               } > REGION_RODATA
             .data : AT (rodata_end)
               {
                 data_start = .;
                 *(.data)
               } > REGION_DATA
             data_size = SIZEOF(.data);
             data_load_start = LOADADDR(.data);
             .bss :
               {
                 *(.bss)
               } > REGION_BSS
           }

Now we need three different `linkcmds.memory` files to define memory regions and alias names. The content of `linkcmds.memory` for the three variants `A`, `B` and `C`:

`A`
  Here everything goes into the `RAM`.

                MEMORY
                  {
                    RAM : ORIGIN = 0, LENGTH = 4M
                  }

                REGION_ALIAS("REGION_TEXT", RAM);
                REGION_ALIAS("REGION_RODATA", RAM);
                REGION_ALIAS("REGION_DATA", RAM);
                REGION_ALIAS("REGION_BSS", RAM);

`B`
  Program code and read-only data go into the `ROM`. Read-write data goes into the `RAM`. An image of the initialized data is loaded into the `ROM` and will be copied during system start into the `RAM`.

                MEMORY
                  {
                    ROM : ORIGIN = 0, LENGTH = 3M
                    RAM : ORIGIN = 0x10000000, LENGTH = 1M
                  }

                REGION_ALIAS("REGION_TEXT", ROM);
                REGION_ALIAS("REGION_RODATA", ROM);
                REGION_ALIAS("REGION_DATA", RAM);
                REGION_ALIAS("REGION_BSS", RAM);

`C`
  Program code goes into the `ROM`. Read-only data goes into the `ROM2`. Read-write data goes into the `RAM`. An image of the initialized data is loaded into the `ROM2` and will be copied during system start into the `RAM`.

                MEMORY
                  {
                    ROM : ORIGIN = 0, LENGTH = 2M
                    ROM2 : ORIGIN = 0x10000000, LENGTH = 1M
                    RAM : ORIGIN = 0x20000000, LENGTH = 1M
                  }

                REGION_ALIAS("REGION_TEXT", ROM);
                REGION_ALIAS("REGION_RODATA", ROM2);
                REGION_ALIAS("REGION_DATA", RAM);
                REGION_ALIAS("REGION_BSS", RAM);

It is possible to write a common system initialization routine to copy the `.data` section from `ROM` or `ROM2` into the `RAM` if necessary:

         #include <string.h>

         extern char data_start [];
         extern char data_size [];
         extern char data_load_start [];

         void copy_data(void)
         {
           if (data_start != data_load_start)
             {
               memcpy(data_start, data_load_start, (size_t) data_size);
             }
         }