EmbeddedRelated.com
Forums

can't setup gnu linker script to output .data into flash

Started by Christopher Harvey October 20, 2011
On 20/10/11 08:19 PM, Mark wrote:
> The following is not going to answer your question, but does explain
> what you have....
>
> what you are asking of the linker is to reserve space in RAM. The code
> is linked to the location in 'flash' as described in your memory map.
> You would need to copy the bytes from flash into RAM in your startup
> script as an additional step. Look at the .data section in the startup
> script and compare it with your linker script, for example.

You're describing exactly what I'm trying to do. My question is why,
given the script below, is my data section linked into the address
0x40000000 (the start of ram)? I can't copy it into ram if it's already
there.

>
> --- In l... ,
> Christopher Harvey wrote:
> >
> > I've having trouble getting gnu ld to output my .data section into
> > flash. Here is the snippet in my ld script:
> >
> > MEMORY
> > {
> > flash : ORIGIN = 0x00000000, LENGTH = 512K
> > ram : ORIGIN = 0x40000000, LENGTH = 32K
> > usbram : ORIGIN = 0x7FD00000, LENGTH = 8K
> > ethram : ORIGIN = 0x7FE00000, LENGTH = 16K
> > }
> >
> > [snip]
> >
> > .data :
> > {
> > __data_beg__ = .;
> > __data_beg_src__ = __end_of_text__;
> > *(.data)
> > __data_end__ = .;
> > } >ram AT>flash
> >
> > and the output of a global array that gets linked with that script.
> >
> > int foo[] = {1,2,3,4,5,6};
> >
> > 40000000 <__data_beg__>:
> > 40000000: 00000001 andeq r0, r0, r1
> > 40000004: 00000002 andeq r0, r0, r2
> > 40000008: 00000003 andeq r0, r0, r3
> > 4000000c: 00000004 andeq r0, r0, r4
> > 40000010: 00000005 andeq r0, r0, r5
> > 40000014: 00000006 andeq r0, r0, r6
> >
> > Notice that it's in RAM. I thought that saying "AT>flash" would place
> > it after the .text section.
> >
> > I also posted this question on stack overflow if anybody prefers to
> > read it there.
> >
> >
> http://stackoverflow.com/questions/7831308/linker-script-load-vs-virtual-address
> >
> > thanks.
> >

An Engineer's Guide to the LPC2100 Series

Looking back a few years ( 2002 ) at the code I wrote for the Leon ( SPARC )
using GCC, the syntax below worked.

.data __DataExecStart : AT (__DataImageStart){
*.o(.ahbram)
data_start = .;
_data_start = .;
_sdata = . ;
*(.data)
*(.gnu.linkonce.d*)
*(.gcc_except_table)
. = ALIGN(0x10);
edata = .;
_edata = .;
}

So here the location was specified at the start of the block definition.

Your syntax would be

.data ram : AT flash{
__data_beg__ = .;
*(.data)
__data_end__ = .;
}

__data_beg_src__ = __end_of_text__;

I know that the linker scripts were a pain to get working originally.

The full linker script is below, note this also had scratch ram and was for
C++, so it built a list of constructors to call, this might be helpful to
some.
It also ensured that the required debug info was in the elf file for
debugging and for the flash programmer to load, this also handles dynamic
overlays

OUTPUT_ARCH(sparc)
__DYNAMIC = 1;
/*
* The memory map looks like this:
* +--------------------+ <- low memory
* | .text |
* | etext |
* | ctor list | the ctor and dtor lists are for
* | dtor list | C++ support
* | _endtext |
* +--------------------+
* | .data | initialized data goes here
* | _sdata |
* | _edata |
* +--------------------+
* | .bss |
* | __bss_start | start of bss, cleared by crt0
* | _end | start of heap, used by sbrk()
* +--------------------+
* | heap space |
* | _ENDHEAP |
* | stack space |
* | __stack | top of stack
* +--------------------+ <- high memory
*/
/* Default values, can be overridden */

_PROM_SIZE = 1M;
_RAM_SIZE = 2M;
_RAM_1_SIZE = 1M;
_AHB_RAM_SIZE = 32K;
_SCRATCH_RAM_SIZE = 32k;
_REG_TABLE_SIZE = 8 * 4 * 19;

_RAM_START = 0x00000000;
_RAM_END = _RAM_START + _RAM_SIZE;

_RAM1_START = 0x02000000;
_RAM1_END = _RAM1_START + _RAM_1_SIZE;

_PROM_START = 0x01000000;
_PROM_END = _PROM_START + _PROM_SIZE - _SCRATCH_RAM_SIZE - _REG_TABLE_SIZE;

_AHB_RAM_START = 0x70000000;
_AHB_RAM_END = _AHB_RAM_START + _AHB_RAM_SIZE;

_SCRATCH_RAM_START = 0xA0000000;
_SCRATCH_RAM_END = _SCRATCH_RAM_START + _SCRATCH_RAM_SIZE;
_REG_DUMP_BASE = _PROM_END;
/* where we copy registers on error */
_SCRATCH_RAM_IMAGE_BASE = _REG_DUMP_BASE + _REG_TABLE_SIZE; /* where we
copy scratch ram on error */

/*
* Alternate names without leading _;
*/

PROM_START = _PROM_START;
PROM_SIZE = _PROM_SIZE;
PROM_END = _PROM_END;

RAM_START = _RAM_START;
RAM_SIZE = _RAM_SIZE;
RAM_END = _RAM_END;

AHB_RAM_START = _AHB_RAM_START;
AHB_RAM_SIZE = _AHB_RAM_SIZE;
AHB_RAM_END = _AHB_RAM_END;

USR_STACK_BASE = RAM_END - 8;

SCRATCH_RAM_START = _SCRATCH_RAM_START;
SCRATCH_RAM_END = _SCRATCH_RAM_END;
SCRATCH_RAM_SIZE = _SCRATCH_RAM_SIZE;
SCRATCH_RAM_IMAGE_BASE = _SCRATCH_RAM_IMAGE_BASE;
REG_DUMP_BASE = _REG_DUMP_BASE;
SECTIONS {

.text _RAM_START : AT ( _RAM_START ) {
CREATE_OBJECT_SYMBOLS
text_start = .;
_text_start = .;
*.o(.text)
*.o(.text*)
. = ALIGN (16);

*.o(.eh_frame)

*(.gnu.linkonce.t*)

/*
* C++ constructors
*/
__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__ = .;

_rodata_start = . ;
*(.rodata)
*(.gnu.linkonce.r*)
_erodata = ALIGN( 0x10 ) ;

etext = ALIGN(0x10);
_etext = .;
*(.init)
*(.fini)
*(.lit)
*(.shdata)
. = ALIGN (16);
_endtext = .;
}

AhbImageStart = .;
AhbExecStart = AHB_RAM_START; /* provided for relocator */

.ahbram AHB_RAM_START : AT (AhbImageStart) {
ahbram_start = .;
_ahbram_start = .;
*(.ahbram)
}

__DataExecStart = _AHB_RAM_START + SIZEOF(.ahbram);
__DataImageStart = AhbImageStart + SIZEOF(.ahbram);

.dynamic : { *(.dynamic) }
.got : { *(.got) }
.plt : { *(.plt) }
.hash : { *(.hash) }
.dynrel : { *(.dynrel) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.hash : { *(.hash) }
.data __DataExecStart : AT (__DataImageStart){
*.o(.ahbram)
data_start = .;
_data_start = .;
_sdata = . ;
*(.data)
*(.gnu.linkonce.d*)
*(.gcc_except_table)
. = ALIGN(0x10);
edata = .;
_edata = .;
}
.shbss : {
*(.shbss)
}
.bss :{
__bss_start = ALIGN(0x8);
_bss_start = .;
bss_start = .;
*(.bss)
*(COMMON)
end = .;
_end = ALIGN(0x8);
__end = ALIGN(0x8);
}
.stab . (NOLOAD) :{
[ .stab ]
}
.stabstr . (NOLOAD) :{
[ .stabstr ]
}
.test_out _RAM1_START : {
test_out_start = .;
_test_out_start = .;
*(.test_out)
}
.scratch SCRATCH_RAM_START : {
scratch_start = .;
_scratch_start = .;
*(.scratch)
}

}

Regards

Phil.

-----Original Message-----
From: l... [mailto:l...] On Behalf Of
Christopher Harvey
Sent: 21 October 2011 04:19
To: l...
Cc: Mark
Subject: Re: [lpc2000] Re: can't setup gnu linker script to output .data
into flash

On 20/10/11 08:19 PM, Mark wrote:
> The following is not going to answer your question, but does explain
> what you have....
>
> what you are asking of the linker is to reserve space in RAM. The code
> is linked to the location in 'flash' as described in your memory map.
> You would need to copy the bytes from flash into RAM in your startup
> script as an additional step. Look at the .data section in the startup
> script and compare it with your linker script, for example.

You're describing exactly what I'm trying to do. My question is why,
given the script below, is my data section linked into the address
0x40000000 (the start of ram)? I can't copy it into ram if it's already
there.

>
> --- In l... ,
> Christopher Harvey wrote:
> >
> > I've having trouble getting gnu ld to output my .data section into
> > flash. Here is the snippet in my ld script:
> >
> > MEMORY
> > {
> > flash : ORIGIN = 0x00000000, LENGTH = 512K
> > ram : ORIGIN = 0x40000000, LENGTH = 32K
> > usbram : ORIGIN = 0x7FD00000, LENGTH = 8K
> > ethram : ORIGIN = 0x7FE00000, LENGTH = 16K
> > }
> >
> > [snip]
> >
> > .data :
> > {
> > __data_beg__ = .;
> > __data_beg_src__ = __end_of_text__;
> > *(.data)
> > __data_end__ = .;
> > } >ram AT>flash
> >
> > and the output of a global array that gets linked with that script.
> >
> > int foo[] = {1,2,3,4,5,6};
> >
> > 40000000 <__data_beg__>:
> > 40000000: 00000001 andeq r0, r0, r1
> > 40000004: 00000002 andeq r0, r0, r2
> > 40000008: 00000003 andeq r0, r0, r3
> > 4000000c: 00000004 andeq r0, r0, r4
> > 40000010: 00000005 andeq r0, r0, r5
> > 40000014: 00000006 andeq r0, r0, r6
> >
> > Notice that it's in RAM. I thought that saying "AT>flash" would place
> > it after the .text section.
> >
> > I also posted this question on stack overflow if anybody prefers to
> > read it there.
> >
> http://stackoverflow.com/questions/7831308/linker-script-load-vs-virtual-add
ress
> >
> > thanks.
> >