Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
21 years ago

Linker (NIOS2-ELF-LD) help requested

We're using Accelerated Technology's Nucleus PLUS RTOS in a product that we're designing. For one part of it, we need to fix a constant structure at a known location in Flash.

Altera didn't seem to include any documentation on the linker (NIOS2-ELF-LD) or the .LD file.

Can anyone point me in the right direction?

The linker is GNU-based, correct? So GNU's LD docs should be applicable?

John

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    NetJohn,

    > For one part of it, we need to fix a constant structure at a known

    > location in Flash.

    There are several ways you can do this. One way is to

    place the data in it's own section. E.g.:

    C Language:

    struct foo bar __attribute__ ((section (".fixed.struct"))) = { 0 };

    Then locate it at a fixed address with an output section in

    your linker command file. E.g., put the struct at 0xffff0000:

    .fixed.struct 0xffff0000 :
    {
        *(.fixed.struct)
    }

    Another way (which I prefer) is to put the struct definition

    in it's _own_ C module. E.g.: in module foo.c:

    struct foo bar =  {some initialized data };

    Then locate module's .data section at a fixed address with an

    output section in your linker command file. E.g.:

    .fixed.struct 0xffff0000 :
    {
        foo.o (.data)
    }

    If the data isn't initialized use .bss.

    > Can anyone point me in the right direction?

    A little dated, but most of the good stuff hasn't changed

    much:

    http://www.gnu.org/software/binutils/manua...d-2.9.1/ld.html (http://www.gnu.org/software/binutils/manual/ld-2.9.1/ld.html)

    Or try use info ld on a linux system.

    > The linker is GNU-based, correct?

    Yes.

    > So GNU's LD docs should be applicable?

    Yes.

    Regards,

    --Scott
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Sorry ... forgot: if it's a const e.g.

    const struct foo bar = {...};

    The input section will be .rodata

    Also for initialized data, the size of the struct and the compiler -G option will

    affect the struct's placement in the .data section or the .sdata section.

    By default, if the struct is (better check me on this) 8 bytes or less,

    it'll be in .sdata, otherwise in .data.

    Regards,

    --Scott
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I have a similar problem where I want to put an array at a fixed ram location for dual-port access. I have put my array in its own c source as smcnutt suggested

    File spectrRam.c -> unsigned long spect[1024];

    Created a linker command file

    file linkerCmds.txt ->
    SECTIONS{
    .fixed.struct 0x00004000 :
    {
       obj/spectrRam.o (.bss)
    }
    }

    But the problem is to get the linker to accept the commands, because as I get from another forum thead, the linking is done by the nios2-elf-gcc NOT the linker, so for instance to get a Map generated one has to use the compiler option

    -Wl,-Map,myMapFile.map
    to get a mapfile created in the project directory.

    Along this line I have tried
    -Wl,-T,linkerCmds.txt
    as well as
    -Wl,-Map,myMapFile.map,-T,linkerCmds.txt  
    in order to get a Map handy for verification of success, but it seems not to work.

    The build gives info like

    nios2-elf-gcc -xc -MD -c -DSYSTEM_BUS_WIDTH=32 -Dexit=_exit -I.. -IC:/PC6479/a_fft/software/peakFind_syslib/Debug/system_description  -I/cygdrive/c/Programs/altera/kits/nios2/components/altera_nios2/HAL/inc  -I/cygdrive/c/Programs/altera/kits/nios2/components/altera_hal/HAL/inc -D__hal__ -DALT_DEBUG -Wl,-T,linkerCmds.txt  -O0 -g -Wall -o obj/spectrRam.o ../spectrRam.c 
    nios2-elf-gcc: -T: linker input file unused because linking not done
    nios2-elf-gcc: linkerCmds.txt: linker input file unused because linking not done

    So the linker is not called/used and the compiler does not recognize the command. Have you a suggestion how to get this solved? I have to say that I am an absolute newcomer to gnu tools.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The problem here is that you've added the flags as compiler rather than linker flags. It is a little confusing that gcc is being used as the front end to both the compiler and the linker, however when you have flags that you want to use at link time then you need to specify them as linker flags rather than compiler flags.

    In any case, if you want to override the linker script being used by the IDE to build HAL projects then you should instead go to the system library properties page and select "custom linker script". You can then specify the linker script you want to use in the box provided (note the file has to be in the project to be locatable).

    That said, there is an even easier way to go about this. Rather than creating a custom linker script, you can free up memory by simply moving the start of the stack downwards. The stack is defined to grow downwards from the address __alt_data_end. This symbol is defined in the linker script. You can override this definition by using the linker flag:

    -Wl,--defsym,__alt_data_end=0x300000

    where 0x300000 is the address you now want the stack to grow down from. Memory above this will be unused by the HAL, and so you're free to use it for whatever you want.

    You can even use this to locate the stack in a memory other than the one used to hold the .rwdata section (which is the default action of the linker script).