summaryrefslogtreecommitdiffstats
path: root/doc/bsp_howto/linkcmds.t
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-10-20 13:49:43 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-10-20 13:49:43 +0000
commit4ed0f06d829358248a7751b22b6558ffc2981893 (patch)
treed5d02f38486b0e8e574ed6ad29f81f2460c839b2 /doc/bsp_howto/linkcmds.t
parentAdded initial cut at some of the libc chapters. (diff)
downloadrtems-4ed0f06d829358248a7751b22b6558ffc2981893.tar.bz2
Added numerous comments to the linker script.
Now this chapter has no two column stuff in it.
Diffstat (limited to 'doc/bsp_howto/linkcmds.t')
-rw-r--r--doc/bsp_howto/linkcmds.t514
1 files changed, 271 insertions, 243 deletions
diff --git a/doc/bsp_howto/linkcmds.t b/doc/bsp_howto/linkcmds.t
index c655117362..4b7b7829ac 100644
--- a/doc/bsp_howto/linkcmds.t
+++ b/doc/bsp_howto/linkcmds.t
@@ -27,25 +27,9 @@ development: the target will execute the program each time it's reboot or
switched on, which means the program is stored in ROM. On the other hand,
data processing occurs in RAM.
-The following example shows a simple layout of program sections. With
-some object formats, there are many more sections but the basic
-layout is conceptually similar.
-
-@example
-@group
- +-----------------+
- | .text | RAM or ROM
- +-----------------+
- | .data | RAM
- +-----------------+
- | .bss | RAM
- +-----------------+
-@end group
-@end example
-
-
-That leads us to the structure of an embedded program: it's roughly made
-of sections, for instance for the Motorola 68k family of microprocessors :
+This leads us to the structure of an embedded program: it is roughly made
+of sections. For example, if using COFF on the Motorola m68k family
+of microprocessors, then the following sections will be present.
@table @b
@@ -69,279 +53,330 @@ to predefined values, which have to be stored in ROM...
That brings us up to the notion of the image of an executable: it consists
in the set of the program sections.
-
-
As a program executable has many sections (note that the user can define
his own, and that compilers define theirs without any notice), one has to
state in which type of memory (RAM or ROM) the sections will be arranged.
-For instance, a program compiled f or a Personal Computer will see all the
+For instance, a program compiled for a Personal Computer will see all the
sections to go to RAM, while a program destined to be embedded will see
some of his sections going into the ROM.
-
-
-The (section, area of memory) connection is made at linking time. One have
-to make the linker know the different sections location once they're in
+The connection between a section and where that section is loaded into
+memory is made at link time. One has to let the linker know where
+the different sections location are to be placed once they are in
memory.
+The following example shows a simple layout of program sections. With
+some object formats, there are many more sections but the basic
+layout is conceptually similar.
-Figure 2 : sections location in memory
+@example
+@group
+ +-----------------+
+ | .text | RAM or ROM
+ +-----------------+
+ | .data | RAM
+ +-----------------+
+ | .bss | RAM
+ +-----------------+
+@end group
+@end example
-The GNU linker has a command language to specify the image format. Let's
-have a look to the "gen68340" BSP linkcmds, which can be found at
+The GNU linker has a command language to specify the image format. This
+command language can be quite complicated but most of what is required
+can be learned by careful examination of a well-documented example.
+The following is a heavily commented version of the linker script
+used with the the @code{gen68340} BSP This file can be found at
$BSP340_ROOT/startup/linkcmds.
@example
-OUTPUT_FORMAT(coff-m68k)
-
-RamSize = DEFINED(RamSize) ? RamSize : 4M;
-HeapSize = DEFINED(HeapSize) ? HeapSize : 0x10000;
-StackSize = DEFINED(StackSize) ? StackSize : 0x1000;
-
-MEMORY @{
- ram : ORIGIN = 0x10000000, LENGTH = 4M
- rom : ORIGIN = 0x01000000, LENGTH = 4M
-@}
-
-ETHERNET_ADDRESS = DEFINED(ETHERNET_ADDRESS) ? ETHERNET_ADDRESS : 0xDEAD12;
-
/*
- * Load objects
+ * Specify that the output is to be coff-m68k regardless of what the
+ * native object format is.
*/
-SECTIONS @{
- /*
- * Hardware variations
- */
- _RamSize = RamSize;
- __RamSize = RamSize;
-
- /*
- * Boot PROM
- */
- rom : @{
- _RomBase = .;
- __RomBase = .;
- @} >rom
-
- /*
- * Dynamic RAM
- */
- ram : @{
- _RamBase = .;
- __RamBase = .;
- @} >ram
-
- /*
- * Text, data and bss segments
- */
- .text : @{
- CREATE_OBJECT_SYMBOLS
-
-
- *(.text)
-
-
- . = ALIGN (16);
-
-
- /*
- * C++ constructors
- */
- __CTOR_LIST__ = .;
- [......]
- __DTOR_END__ = .;
-
- etext = .;
- _etext = .;
- @} >rom
-
- .eh_fram : @{
- . = ALIGN (16);
- *(.eh_fram)
- @} >ram
-
- .gcc_exc : @{
- . = ALIGN (16);
- *(.gcc_exc)
- @} >ram
-
- dpram : @{
- m340 = .;
- _m340 = .;
- . += (8 * 1024);
- @} >ram
-
- .data : @{
- copy_start = .;
- *(.data)
- . = ALIGN (16);
- _edata = .;
- copy_end = .;
- @} >ram
-
- .bss : @{
- M68Kvec = .;
- _M68Kvec = .;
- . += (256 * 4);
-
-
- clear_start = .;
-
- *(.bss)
+OUTPUT_FORMAT(coff-m68k)
- *(COMMON)
+/*
+ * Set the amount of RAM on the target board.
+ *
+ * NOTE: The default may be overridden by passing an argument to ld.
+ */
- . = ALIGN (16);
- _end = .;
+RamSize = DEFINED(RamSize) ? RamSize : 4M;
- _HeapStart = .;
- __HeapStart = .;
- . += HeapSize;
- . += StackSize;
- . = ALIGN (16);
- stack_init = .;
+/*
+ * Set the amount of RAM to be used for the application heap. Objects
+ * allocated using malloc() come from this area. Having a tight heap size
+ * is somewhat difficult and multiple attempts to squeeze it may be needed
+ * if you want to save the memory usage. If you allocate all objects from
+ * the heap at system initialization time, this eases the sizing of the
+ * application heap.
+ *
+ * NOTE 1: The default may be overridden by passing an argument to ld.
+ *
+ * NOTE 2: The TCP/IP stack requires additional memory in the Heap.
+ *
+ * NOTE 3: The GNAT/RTEMS run-time requires additional memory in the Heap.
+ */
- clear_end = .;
+HeapSize = DEFINED(HeapSize) ? HeapSize : 0x10000;
- _WorkspaceBase = .;
- __WorkspaceBase = .;
+/*
+ * Set the size of the starting stack used during BSP initialization
+ * until first task switch. After that point, task stacks allocated
+ * by RTEMS are used.
+ *
+ * NOTE: The default may be overridden by passing an argument to ld.
+ */
+StackSize = DEFINED(StackSize) ? StackSize : 0x1000;
+/*
+ * Starting addresses and length of RAM and ROM.
+ *
+ * The addresses must be valid addresses on the board. The Chip Selects
+ * should be initialized such that the code addresses are valid.
+ */
- @} >ram
+MEMORY @{
+ ram : ORIGIN = 0x10000000, LENGTH = 4M
+ rom : ORIGIN = 0x01000000, LENGTH = 4M
@}
-@end example
-
-executable format is COFF
-
-your default board RAM size here.
-
-Note that it's possible to change it by passing an argument to ld
-
-the default heap size: beware! the heap must be large enough to contain:
-
-@itemize @bullet
-
-@item your program's static allocations
-
-@item your program's dynamic allocations
-
-@item ALL YOUR PROCESS'S STACK
-
-@end itemize
-
-Having a tight heap size is somewhat difficult and many tries are needed
-if you want to save the memory usage.
-
-
-The Stacksize should only be large enough to hold the stack in the
-initialization sequence. Then the tasks stacks will be allocated in the
-Heap.
-
-Start address of RAM and its length.
-The start address must be a valid address. Most often RAM is assigned to a
-given chip of memory on the board, and a Chip Select is assigned to this
-chip with an address (see the Initialization sequence chapter).
-
-
-Start address of ROM and its length. Same remarks as above.
-
-this is for the network driver (see Networking documentation for more details)
-
-define where the sections should go:
-
-define some variables that the user code can access.
-
-set the RomBase variable to the start of the ROM.
-
-set the RamBase variable to the start of the RAM.
-
-states that a symbol shall be created for each object (.o)
-
-insert the @code{.text} sections of every object
-
-go to a frontier of 16 bytes (just keep it as is)
-
-reserve some place for C++ constructors and destructors.
-
-just keep it as is (or see CROSSGCC mailing-list FAQ for more details)
+/*
+ * This is for the network driver. See the Networking documentation
+ * for more details.
+ */
-declares where the @code{.text} section ends.
+ETHERNET_ADDRESS = DEFINED(ETHERNET_ADDRESS) ? ETHERNET_ADDRESS : 0xDEAD12;
-the @code{.text} section goes in ROM!
+/*
+ * The following defines the order in which the sections should go.
+ * It also defines a number of variables which can be used by the
+ * application program.
+ *
+ * NOTE: Each variable appears with 1 or 2 leading underscores to insure
+ * that the variable is accessible from C code with a single
+ * underscore. Some object formats automatically add a leading
+ * underscore to all C global symbols.
+ */
-this section is created by GCC
+SECTIONS @{
-put it in RAM.
+ /*
+ * Make the RomBase variable available to the application.
+ */
+
+ _RamSize = RamSize;
+ __RamSize = RamSize;
+
+ /*
+ * Boot PROM - Set the RomBase variable to the start of the ROM.
+ */
+
+ rom : @{
+ _RomBase = .;
+ __RomBase = .;
+ @} >rom
+
+ /*
+ * Dynamic RAM - set the RamBase variable to the start of the RAM.
+ */
+
+ ram : @{
+ _RamBase = .;
+ __RamBase = .;
+ @} >ram
-this section is created by GCC
+ /*
+ * Text (code) goes into ROM
+ */
+
+ .text : @{
+ /*
+ * Create a symbol for each object (.o).
+ */
-put it in RAM
+ CREATE_OBJECT_SYMBOLS
-room for peripherals
+ /*
+ * Put all the object files code sections here.
+ */
-needs 8 Kbytes
-put it in RAM
+ *(.text)
-the initialized data section
+ . = ALIGN (16); /* go to a 16-byte boundary */
-put all the objects' .data sections in the .data section of the image
+ /*
+ * C++ constructors and destructors
+ *
+ * NOTE: See the CROSSGCC mailing-list FAQ for
+ * more details about the "[......]".
+ */
-.data section goes in RAM
+ __CTOR_LIST__ = .;
+ [......]
+ __DTOR_END__ = .;
-the non initialized data section
+ /*
+ * Declares where the .text section ends.
+ */
+ etext = .;
+ _etext = .;
+ @} >rom
-reserve some room for the Table of Vector Interrupts (256 vectors of 4 bytes)
+ /*
+ * Exception Handler Frame section
+ */
-pointer to the start of the non initialized data
+ .eh_fram : @{
+ . = ALIGN (16);
+ *(.eh_fram)
+ @} >ram
-put all the objects .bss sections in the .bss section of the image
+ /*
+ * GCC Exception section
+ */
-put all the non initialized data, which are not in .bss sections
+ .gcc_exc : @{
+ . = ALIGN (16);
+ *(.gcc_exc)
+ @} >ram
-Heap start
+ /*
+ * Special variable to let application get to the dual-ported
+ * memory.
+ */
-reserve some room for the heap
+ dpram : @{
+ m340 = .;
+ _m340 = .;
+ . += (8 * 1024);
+ @} >ram
-reserve some room for the stack
+ /*
+ * Initialized Data section goes in RAM
+ */
-top of the stack (remember the stack grows with addresses going down)
+ .data : @{
+ copy_start = .;
+ *(.data)
-end of the non initialized data
+ . = ALIGN (16);
+ _edata = .;
+ copy_end = .;
+ @} >ram
+
+ /*
+ * Uninitialized Data section goes in ROM
+ */
+
+ .bss : @{
+ /*
+ * M68K specific: Reserve some room for the Vector Table
+ * (256 vectors of 4 bytes).
+ */
-start of the RTEMS Workspace (holds RTEMS configuration table and a few
-other things, its size is calculated by RTEMS according to your
-configuration, <INSERT A LINK HERE>)
+ M68Kvec = .;
+ _M68Kvec = .;
+ . += (256 * 4);
-the resulting .bss section goes in RAM
+ /*
+ * Start of memory to zero out at initialization time.
+ */
+ clear_start = .;
-Now there's a problem with the initialized data: the .data section has to
-be in RAM as these data are to be modified during the program execution.
-But how will they be initialized at boot time?
+ /*
+ * Put all the object files uninitialized data sections
+ * here.
+ */
+
+ *(.bss)
+ *(COMMON)
+ . = ALIGN (16);
+ _end = .;
+
+ /*
+ * Start of the Application Heap
+ */
+
+ _HeapStart = .;
+ __HeapStart = .;
+ . += HeapSize;
+
+ /*
+ * The Starting Stack goes after the Application Heap.
+ * M68K stack grows down so start at high address.
+ */
+
+ . += StackSize;
+ . = ALIGN (16);
+ stack_init = .;
+
+ clear_end = .;
+
+ /*
+ * The RTEMS Executive Workspace goes here. RTEMS
+ * allocates tasks, stacks, semaphores, etc. from this
+ * memory.
+ */
+
+ _WorkspaceBase = .;
+ __WorkspaceBase = .;
+ @} >ram
+@}
+@end example
-One should be aware of the running executable image and the file to
-download to the target image being different! In practice, the initialized
-data section is copied at the end of the code section (i.e. in ROM) when
-building a PROM image. The GNU tool obj copy can be used for this purpose.
+Now there's a problem with the initialized data: the @code{.data} section
+has to be in RAM as these data may be modified during the program execution.
+But how will the values be initialized at boot time?
+One approach is to place the entire program image in RAM and reload
+the image in its entirety each time the program is run. This is fine
+for use in a debug environment where a high-speed connection is available
+between the development host computer and the target. But even in this
+environment, it is cumbersome.
+The solution is to place a copy of the initialized data in a separate
+area of memory and copy it into the proper location each time the
+program is started. It is common practice to place a copy of the initialized
+@code{.data} section the end of the code (@code{.text} section
+(i.e. in ROM) when building a PROM image. The GNU tool @code{objcopy}
+can be used for this purpose.
-Figure 3 : copy of the initialized data section to build a PROM image
+The following figure illustrates the steps a linked program goes through
+to become a downloadabled image.
+@example
+@group
++--------------+ +--------------------+
+| .data RAM | | .data RAM |
++--------------+ +--------------------+
+| .bss RAM | | .bss RAM |
++--------------+ +--------------------+ +----------------+
+| .text ROM | | .text ROM | | .text |
++--------------+ +--------------------+ +----------------+
+ | copy of .data ROM | | copy of .data |
+ +--------------------+ +----------------+
+
+ Step 1 Step 2 Step 3
+@end group
+@end example
+In Step 1, the program is linked together using the BSP linker script.
-This process is made after the linking time, and you can find an example
-of how it is done in $RTEMS_ROOT/make/custom/gen68340.cfg :
+In Step 2, a copy is made of the @code{.data} section and placed
+after the @code{.text} section so it can be placed in PROM. This step
+is done after the linking time. There is an example
+of doing this in the file $RTEMS_ROOT/make/custom/gen68340.cfg:
@example
-# make a prom image
+# make a PROM image using objcopy
m68k-rtems-objcopy \
--adjust-section-vma .data= \
@@ -351,20 +386,13 @@ $(basename $@@).exe \
$(basename $@@).exe
@end example
-use the target objcopy
-
-we want to move the start of the section .data
-
-in the resulting image
-
-the address is given by extracting the address of the end of the @code{.text}
-section (i.e. in ROM) with an awk script (don't care about it)
-
-process the image which have just been linked
-
-
+NOTE: The address at which the copy of the @code{.data} section is
+specified by extracting the address of the end of the @code{.text}
+section (i.e. in ROM) with an @code{awk} script. The details of how
+this is done are not relevant.
-The board initialization code (cf. 6) will copy the initialized data
-initial values (which are stored in ROM) to their reserved location in
-RAM.
+Step 3 shows the final executable image as it logically appears in
+the target's non-volatile program memory. The board initialization
+code will copy the initialized data initial values (which are stored in
+ROM) to their reserved location in RAM.