8.5.6. Placing a Section at Different Load and Run Addresses

At times, you may want to load code into one area of memory and run it in another. For example, you may have performance-critical code in slow external memory. The code must be loaded into slow external memory, but it would run faster in fast external memory.

The linker provides a simple way to accomplish this. You can use the SECTIONS directive to direct the linker to allocate a section twice: once to set its load address and again to set its run address. For example:

.fir: load = SLOW_MEM, run = FAST_MEM

Use the load keyword for the load address and the run keyword for the run address.

See Run-Time Relocation for an overview on run-time relocation.

The application must copy the section from its load address to its run address; this does not happen automatically when you specify a separate run address. (The TABLE operator instructs the linker to produce a copy table; see The table() Operator.)

8.5.6.1. Specifying Load and Run Addresses

The load address determines where a loader places the raw data for the section. Any references to the section (such as labels in it) refer to its run address. See Load and Run Addresses for an overview of load and run addresses.

If you provide only one allocation (either load or run) for a section, the section is allocated only once and loads and runs at the same address. If you provide both allocations, the section is allocated as if it were two sections of the same size. This means that both allocations occupy space in the memory map and cannot overlay each other or other sections. (The UNION directive provides a way to overlay sections; see Overlaying Sections With the UNION Statement.)

If either the load or run address has additional parameters, such as alignment or blocking, list them after the appropriate keyword. Everything related to allocation after the keyword load affects the load address until the keyword run is seen, after which, everything affects the run address. The load and run allocations are completely independent, so any qualification of one (such as alignment) has no effect on the other. You can also specify run first, then load. Use parentheses to improve readability.

The examples that follow specify load and run addresses.

In this example, align applies only to load:

.data: load = SLOW_MEM, align = 32, run = FAST_MEM

The following example uses parentheses, but has effects that are identical to the previous example:

.data: load = (SLOW_MEM align 32), run = FAST_MEM

The following example aligns FAST_MEM to 32 bits for run allocations and aligns all load allocations to 16 bits:

.data: run  = FAST_MEM, align 32, load = align 16

For more information on run-time relocation see Run-Time Relocation.

Uninitialized sections (such as .bss) are not loaded, so their only significant address is the run address. The linker allocates uninitialized sections only once: if you specify both run and load addresses, the linker warns you and ignores the load address. Otherwise, if you specify only one address, the linker treats it as a run address, regardless of whether you call it load or run.

This example specifies load and run addresses for an uninitialized section:

.bss: load = 0x1000, run = FAST_MEM

A warning is issued, load is ignored, and space is allocated in FAST_MEM. All of the following examples have the same effect. The .bss section is allocated in FAST_MEM.

.dbss: load = FAST_MEM
.bss: run = FAST_MEM
.bss: > FAST_MEM

See Using Linker Symbols in C/C++ Applications for information about referring to linker symbols in C/C++ code.