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 */
-----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.
> >
Reply by Christopher Harvey●November 1, 20112011-11-01
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.
> >
Reply by Paul Curtis●November 1, 20112011-11-01
> Hi Paul,
>
> I’m not missing the point, he states he wanted the variable in flash,
> i.e. not variable.
No, the OP stated in a follow-up post:
"The variables are initialized, but they aren't read-only."
I’m not missing the point, he states he wanted the variable in flash, i.e.
not variable.
With GNU it’s different than the ARM tools, but essentially if it is to
be an initialized variable then it needs 2 image addresses, a load address and
an execution address.
For GCC the image will generally contain an exact image of the data init state
at the load address which has to be copied by the loader, ( in a static app by
the startup code ) to the execution address, in ARM tools this is sightly
different since by default they compress the image so it has to be de-compressed
and copied.
If it was truly const then it would be in .rodata not .data, and the load and
execute addresses would be the same. ( section naming conventions also change of
course for different toolchains just to make life harder ).
(one reason that sometimes ARM generates smaller code than GCC, if you have a
lot of initialized data is the compression of the image ).
One thing that gets confusing for people, and I noticed it in some of the
comments to this thread, is the concept of virtual addressing.
Without an MMU the concept of virtual addressing does not apply since all
addresses are physical addresses, and it should not be confused with the load
address and the execution address.
For a system without an MMU the load address is where the physical copy exists
at startup, the execution address is the physical address of where it will be
copied to at runtime.
For a system WITH an MMU, the load address does not change ( for an image in
flash ), but the execution address becomes the virtual address at runtime, the
physical address of the data at runtime is then determined by the systems memory
management algorithm.
Regards
Phil.
From: l... [mailto:l...] On Behalf Of Paul Curtis
Sent: 01 November 2011 09:02
To: l...
Subject: RE: [lpc2000] can't setup gnu linker script to output .data into
flash
> If you want “variables” placed in flash
then obviously they can’t be
> variable, so you must declare them as const.
You seem to be missing the point. There are two images of the data required for
"int x = 5" -- one in flash, one in RAM. It seems as though the OP has some
trouble getting the one in flash set up correctly.
> If you want “variables” placed in flash
then obviously they can’t be
> variable, so you must declare them as const.
You seem to be missing the point. There are two images of the data required for
"int x = 5" -- one in flash, one in RAM. It seems as though the OP has some
trouble getting the one in flash set up correctly.
If you want “variables” placed in flash then obviously they
can’t be variable, so you must declare them as const.
Note that there are sometimes benefits in having “const” data in
RAM, but this is dependent on the bus and processor architecture.
For Von-Neumann architectures ( ARM7 ) it makes no difference since everything
is fetched over a single bus, but for Harvard Architecture processors with
multi-layer AHB or tightly coupled data ram this can improve performance if the
RAM / FLASH can be simultaneously accessed for example over independent AHB
interconnects.
Regards
Phil.
From: l... [mailto:l...] On Behalf Of Christopher Harvey
Sent: 20 October 2011 19:37
To: l...
Subject: Re: [lpc2000] can't setup gnu linker script to output .data into
flash
On Thu, 20 Oct 2011 11:13:41 -0700, David Smead wrote: > Initialized variables should be placed in .rodata
section, not .data
>
> DaveS
The variables are initialized, but they aren't read-only.
>
> On Thu, Oct 20, 2011 at 8:26 AM, 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.
>
>
>
Reply by Christopher Harvey●November 1, 20112011-11-01
On Thu, 20 Oct 2011 11:13:41 -0700, David Smead wrote: > Initialized variables should be placed in .rodata
section, not .data
>
> DaveS
The variables are initialized, but they aren't read-only.
>
> On Thu, Oct 20, 2011 at 8:26 AM, 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.
>
>
>
Reply by Christopher Harvey●October 21, 20112011-10-21
*facepalm*.
I think I figured it out. running objdump -D displays virtual addresses.
So the 0x40000000 values I was worried about are actually in flash.
Running objdump -h showed me a memory map, and indeed the linker script
was doing its job.
On 20/10/11 11:26 AM, 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.
Reply by Mark●October 20, 20112011-10-20
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.
--- 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.
>
Reply by Michael Anton●October 20, 20112011-10-20
Try declaring it as:
const int foo[] = {1,2,3,4,5,6};
as this should put it in the flash constant data area. But, you can't
modify the values then (obviously).
Mike
-----Original Message-----
From: l... [mailto:l...]On Behalf
Of Christopher Harvey
Sent: Thursday, October 20, 2011 9:27 AM
To: l...
Subject: [lpc2000] can't setup gnu linker script to output .data into
flash
I've having trouble getting gnu ld to output my .data section into
flash. Here is the snippet in my ld script: