### 3.2 Linker scripts for memory management

The linker script sets up the memory map of an application. It also sets up default values for variables used elsewhere by sbrk() and the crt0. These default variables are typically called `_bss_start` and `_end`.

For G++, the constructor and destructor tables must also be setup here. The actual section names vary depending on the object file format. For `a.out` and `coff`, the three main sections are `.text`, `.data`, and `.bss`.

Now that you have an image, you can test to make sure it got the memory map right. You can do this by having the linker create a memory map (by using the `-Map` option), or afterwards by using `nm` to check a few critical addresses like `start`, `bss_end`, and `_etext`.

Here’s a breakdown of a linker script for a m68k based target board. See the file `libgloss/m68k/idp.ld`, or go to the appendixes in the end of the manual. Example Linker Script.

    STARTUP(crt0.o)
    OUTPUT_ARCH(m68k)
    INPUT(idp.o)
    SEARCH_DIR(.)
    __DYNAMIC  =  0;

The `STARTUP` command loads the file specified so that it’s first. In this case it also doubles to load the file as well, because the m68k-coff configuration defaults to not linking in the crt0.o by default. It assumes that the developer probably has their own crt0.o. This behavior is controlled in the config file for each architecture. It’s a macro called `STARTFILE_SPEC`, and if it’s set to `null`, then when `gcc` formats it’s command line, it doesn’t add `crto.o`. Any file name can be specified here, but the default is always `crt0.o`.

Course if you only use `ld` to link, then the control of whether or not to link in `crt0.o` is done on the command line. If you have multiple crto files, then you can leave this out all together, and link in the `crt0.o` in the makefile, or by having different linker scripts. Sometimes this is done for initializing floating point optionally, or to add device support.

The `OUTPUT_ARCH` sets architecture the output file is for.

`INPUT` loads in the file specified. In this case, it’s a relocated library that contains the definitions for the low-level functions need by libc.a. This could have also been specified on the command line, but as it’s always needed, it might as well be here as a default. `SEARCH_DIR` specifies the path to look for files, and `_DYNAMIC` means in this case there are no shared libraries.

    /*
     * Setup the memory map of the MC68ec0x0 Board (IDP)
     * stack grows up towards high memory. This works for
     * both the rom68k and the mon68k monitors.
     */
    MEMORY
    {
      ram     : ORIGIN = 0x10000, LENGTH = 2M
    }

This specifies a name for a section that can be referred to later in the script. In this case, it’s only a pointer to the beginning of free RAM space, with an upper limit at 2M. If the output file exceeds the upper limit, it will produce an error message.

    /*
     * stick everything in ram (of course)
     */
    SECTIONS
    {
      .text :
      {
        CREATE_OBJECT_SYMBOLS
        *(.text)
         etext  =  .;
         __CTOR_LIST__ = .;
         LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
        *(.ctors)
         LONG(0)
         __CTOR_END__ = .;
         __DTOR_LIST__ = .;
         LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
        *(.dtors)
         LONG(0)
         __DTOR_END__ = .;
        *(.lit)
        *(.shdata)
      }  > ram
      .shbss SIZEOF(.text) + ADDR(.text) :	{
        *(.shbss)
      }

Set up the `.text` section. In a `COFF` file, .text is where all the actual instructions are. This also sets up the CONTRUCTOR and the DESTRUCTOR tables for `G++`. Notice that the section description redirects itself to the ram variable setup earlier.

      .talias :	 { }  > ram
      .data  : {
        *(.data)
        CONSTRUCTORS
        _edata  =  .;
      } > ram

Setup the `.data` section. In a `coff` file, this is where all he initialized data goes. `CONSTRUCTORS` is a special command used by `ld`.

      .bss SIZEOF(.data) + ADDR(.data) :
      {
       __bss_start = ALIGN(0x8);
       *(.bss)
       *(COMMON)
          end = ALIGN(0x8);
          _end = ALIGN(0x8);
          __end = ALIGN(0x8);
      }
      .mstack  : { }  > ram
      .rstack  : { }  > ram
      .stab  . (NOLOAD) :
      {
        [ .stab ]
      }
      .stabstr  . (NOLOAD) :
      {
        [ .stabstr ]
      }
    }

Setup the `.bss` section. In a `COFF` file, this is where unitialized data goes. The symbols `_bss_start` and `_end` are setup here for use by the `crt0.o` when it zero’s the `.bss` section.