representation of the name is stored.
The developer can define custom sections by invoking the linker command.section. For example, where the source files states
.section my_section
the linker creates a new section called my_section. The reasons for creating custom named sections are explained shortly.
The sh_addr is the address where the program section should reside in the target memory. The p_paddr is the address where the program segment should reside in the target memory. The sh_addr and the p_paddr fields refer to the load addresses. The loader uses the load address field from the section header as the starting address for the image transfer from non-volatile memory to RAM.
For many embedded applications, the run address is the same as the load address. These embedded applications are directly downloaded into the target system memory for immediate execution without the need for any code or data transfer from one memory type or location to another. This practice is common during the development phase. We revisit this topic in Chapter 3, which covers the topic of image transfer from the host system to the target system.
2.4 Mapping Executable Images into Target Embedded Systems
After multiple source files (C/C++ and assembly files) have been compiled and assembled into ELF object files, the linker must combine these object files and merge the sections from the different object files into program segments. This process creates a single executable image for the target embedded system. The embedded developer uses linker commands (called
2.4.1 Linker Command File
The format of the linker command file, as well as the linker directives, vary from linker to linker. It is best to consult the programmer’s reference manual from the vendor for specific linker commands, syntaxes, and extensions. Some common directives, however, are found among the majority of the available linkers used for building embedded applications. Two of the more common directives supported by most linkers are MEMORY and SECTION.
The MEMORY directive can be used to describe the target system’s
Figure 2.5: Simplified schematic and memory map for a target system.
The linker combines input sections having the same name into a single output section with that name by default. The developer-created, custom-named sections appear in the object file as independent sections. Sometimes developers might want to change this default linker behavior of only coalescing sections with the same name. The embedded developer might also need to instruct the linker on where to map the sections, in other words, what addresses should the linker use when performing symbol resolutions. The embedded developer can use the SECTION directive to achieve these goals.
The MEMORY directive defines the types of physical memory present on the target system and the address range occupied by each physical memory block, as specified in the following generalized syntax
MEMORY {
area-name: org = start-address, len = number-of-bytes
…
}
In the example shown in Figure 2.5, three physical blocks of memory are present:
· a ROM chip mapped to address space location 0, with 32 bytes,
· some flash memory mapped to address space location 0x40, with 4,096 bytes, and
· a block of RAM that starts at origin 0x10000, with 65,536 bytes.
Translating this memory map into the MEMORY directive is shown in Listing 2.2. The named areas are ROM, FLASH, and RAM.
Listing 2.2: Memory map.
MEMORY {
ROM: origin = 0x0000h, length = 0x0020h
FLASH: origin = 0x0040h, length = 0x1000h
RAM: origin = 0x1000h, length = 0x10000h
}
The SECTION directive tells the linker which input sections are to be combined into which output section, which output sections are to be grouped together and allocated in contiguous memory, and where to place each section, as well as other information. A general notation of the SECTION command is shown in Listing 2.3.
Listing 2.3: SECTION command.
SECTION {
output-section-name: {contents} › area-name
…
GROUP {
[ALIGN(expression)]
section-definition
…
} › area-name
}
The example shown in Figure 2.6 contains three default sections (.text,.data, and.bss), as well as two developer-specified sections (loader and my_section), contained in two object files generated by a compiler or assembler (file1.o and file2.o). Translating this example into the MEMORY directive is shown in Listing 2.4.
Figure 2.6: Combining input sections into an executable image.
Listing 2.4: Example code.
SECTION {
.text:
{
my_section
*(.text)
}
loader: › FLASH