How to specify the location of an object in memory (GNU)
2005-11-01 by Michel Kuenemann
Yahoo Groups archive
Index last updated: 2026-04-28 23:31 UTC
Thread
2005-11-01 by Michel Kuenemann
Dear LPC2000 Group, I am using the KEIL IDE for ARM7 processors with the GNU Cygnus compiler on a LPC2106 target. My problem is that I cannot find in the documentation how to tell the compiler to locate an object at a specified place (somwhere in flash memory, for instance). In another IDE I am using, I would write : at 0x00016000 int base; Can someone help me ? Thank you. Michel Kuenemann KMS - France
2005-11-01 by Tom Walsh
Michel Kuenemann wrote: >Dear LPC2000 Group, > >I am using the KEIL IDE for ARM7 processors with the GNU Cygnus compiler on >a LPC2106 target. My >problem is that I cannot find in the documentation how to tell the compiler >to locate an object at a specified place (somwhere in flash memory, for >instance). > > > That would be the linker that would do the physical location of things. Compilers build relocatable objects, linkers place those into regions that you specify in the linker file (script). TomW >In another IDE I am using, I would write : > >at 0x00016000 int base; > >Can someone help me ? > >Thank you. > >Michel Kuenemann >KMS - France > > > > > > >Yahoo! Groups Links > > > > > > > > -- Tom Walsh - WN3L - Embedded Systems Consultant http://openhardware.net, http://cyberiansoftware.com "Windows? No thanks, I have work to do..." ----------------------------------------------------
2005-11-01 by Tom Walsh
Tom Walsh wrote: >Michel Kuenemann wrote: > > > >>Dear LPC2000 Group, >> >>I am using the KEIL IDE for ARM7 processors with the GNU Cygnus compiler on >>a LPC2106 target. My >>problem is that I cannot find in the documentation how to tell the compiler >>to locate an object at a specified place (somwhere in flash memory, for >>instance). >> >> >> >> >> >That would be the linker that would do the physical location of things. > >Compilers build relocatable objects, linkers place those into regions >that you specify in the linker file (script). > > > Go here: http://www.openhardware.net Then under "Documents Lib" select "Absolute Linking with gcc". In that document, look at page 5 to see how things get hardcoded to an absolute address. The document is rather old, I wrote it a number of years ago, however, it is still pertinent to what we do today with the linker. TomW -- Tom Walsh - WN3L - Embedded Systems Consultant http://openhardware.net, http://cyberiansoftware.com "Windows? No thanks, I have work to do..." ----------------------------------------------------
2005-11-01 by David Hawkins
Hey Michel,
Michel wrote:
> I am using the KEIL IDE for ARM7 processors with the GNU Cygnus
> compiler on a LPC2106 target. My problem is that I cannot find
> in the documentation how to tell the compiler to locate an object
> at a specified place (somwhere in flash memory, for instance).
> at 0x00016000 int base;
TomW replied with:
> That would be the linker that would do the physical location of things.
>
> Compilers build relocatable objects, linkers place those into regions
> that you specify in the linker file (script).
Could you please tell us WHY you want to do this?
The only time I can ever think of needed to force a particular
code at a specific address is;
a) an exception vector(s)
b) an overlay for a set of device control registers
For (a) you can define a section, and use the linker script to
perform the locating in Flash. For (b), I've always found it
nicer to just use a pointer to the peripherals region instead,
eg.
typedef struct serial {
int control;
int status;
int data;
} serial_t;
serial_t *com1 = (serial_t *)(SERIAL_BASE_ADDR);
registers are accessed as com1->control = ...
If you use the linker to link this structure over a specific range
of addresses, then the syntax changes to com1.control = ...
But you have to do more work with the linker script.
So, perhaps you are trying to implement something the
difficult way, tell us what you are trying to do.
Cheers,
Dave2005-11-01 by Michel Kuenemann
Hello Tom,
Thank you very much for your tip. I was searching in the wrong direction (as
usual).
Now I think I have found the way I should do this :
1 - In the linker script I declare a section ".iap" that begins at a given
address in the code space.
/* Beginning of the flash sector where I want to store data with IAP */
.iap 0x00016000 :
{
*(.iap)
} >CODE
. = ALIGN(4);
2 - In the C code I write something like :
long star __attribute__ ((section (".iap")));
I guess this will do the thing. I have checked in the map fil that the
address of "star" is 0x00016000.
Regards
Michel Kuenemann
-----Message d'origine-----
De : lpc2000@yahoogroups.com [mailto:lpc2000@yahoogroups.com]De la part de
Tom Walsh
Envoyé : mardi 1 novembre 2005 21:42
À : lpc2000@yahoogroups.com
Objet : Re: [lpc2000] How to specify the location of an object in memory
(GNU)
Tom Walsh wrote:
>Michel Kuenemann wrote:
>
>
>
>>Dear LPC2000 Group,
>>
>>I am using the KEIL IDE for ARM7 processors with the GNU Cygnus compiler
on
>>a LPC2106 target. My
>>problem is that I cannot find in the documentation how to tell the
compiler
>>to locate an object at a specified place (somwhere in flash memory, for
>>instance).
>>
>>
>>
>>
>>
>That would be the linker that would do the physical location of things.
>
>Compilers build relocatable objects, linkers place those into regions
>that you specify in the linker file (script).
>
>
>
Go here: http://www.openhardware.net
Then under "Documents Lib" select "Absolute Linking with gcc". In that
document, look at page 5 to see how things get hardcoded to an absolute
address. The document is rather old, I wrote it a number of years ago,
however, it is still pertinent to what we do today with the linker.
TomW
--
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------
SPONSORED LINKS Microprocessor Microcontrollers Pic microcontrollers
8051 microprocessor
----------------------------------------------------------------------------
--
YAHOO! GROUPS LINKS
a.. Visit your group "lpc2000" on the web.
b.. To unsubscribe from this group, send an email to:
lpc2000-unsubscribe@yahoogroups.com
c.. Your use of Yahoo! Groups is subject to the Yahoo! Terms of
Service.
----------------------------------------------------------------------------
--
[Non-text portions of this message have been removed]2005-11-01 by Michel Kuenemann
Hi David,
You are completely right, I can give any adress the way you show it in your
example.
I can write
long *l = (long *) 0x00016000;
instead of declaring a section beginning at a given address in the linker
script.
Let's say it was a kind of exercise :-)
Regards
Michel Kuenemann
-----Message d'origine-----
De : lpc2000@yahoogroups.com [mailto:lpc2000@yahoogroups.com]De la part de
David Hawkins
Envoyé : mardi 1 novembre 2005 21:45
À : lpc2000@yahoogroups.com
Objet : RE: [lpc2000] How to specify the location of an object in
memory(GNU)
Hey Michel,
Michel wrote:
> I am using the KEIL IDE for ARM7 processors with the GNU Cygnus
> compiler on a LPC2106 target. My problem is that I cannot find
> in the documentation how to tell the compiler to locate an object
> at a specified place (somwhere in flash memory, for instance).
> at 0x00016000 int base;
TomW replied with:
> That would be the linker that would do the physical location of things.
>
> Compilers build relocatable objects, linkers place those into regions
> that you specify in the linker file (script).
Could you please tell us WHY you want to do this?
The only time I can ever think of needed to force a particular
code at a specific address is;
a) an exception vector(s)
b) an overlay for a set of device control registers
For (a) you can define a section, and use the linker script to
perform the locating in Flash. For (b), I've always found it
nicer to just use a pointer to the peripherals region instead,
eg.
typedef struct serial {
int control;
int status;
int data;
} serial_t;
serial_t *com1 = (serial_t *)(SERIAL_BASE_ADDR);
registers are accessed as com1->control = ...
If you use the linker to link this structure over a specific range
of addresses, then the syntax changes to com1.control = ...
But you have to do more work with the linker script.
So, perhaps you are trying to implement something the
difficult way, tell us what you are trying to do.
Cheers,
Dave
----------------------------------------------------------------------------
--
YAHOO! GROUPS LINKS
a.. Visit your group "lpc2000" on the web.
b.. To unsubscribe from this group, send an email to:
lpc2000-unsubscribe@yahoogroups.com
c.. Your use of Yahoo! Groups is subject to the Yahoo! Terms of
Service.
----------------------------------------------------------------------------
--
[Non-text portions of this message have been removed]2005-11-02 by Tom Walsh
David Hawkins wrote:
>Hey Michel,
>
>Michel wrote:
>
>
>>I am using the KEIL IDE for ARM7 processors with the GNU Cygnus
>>compiler on a LPC2106 target. My problem is that I cannot find
>>in the documentation how to tell the compiler to locate an object
>>at a specified place (somwhere in flash memory, for instance).
>>at 0x00016000 int base;
>>
>>
>
>TomW replied with:
>
>
>>That would be the linker that would do the physical location of things.
>>
>>Compilers build relocatable objects, linkers place those into regions
>>that you specify in the linker file (script).
>>
>>
>
>Could you please tell us WHY you want to do this?
>
>The only time I can ever think of needed to force a particular
>code at a specific address is;
>
>
>
Just because you know a couple of things doesn't mean that you know it all.
If you recognized the "AT" directive then you would have understood that
the question was regard to locating a section to a hard address.
Typically this is done to describe where something such as a binary
image produced by something other than the compiler. Or, it is done to
physically locate entire Sections of code into external memory devices.
Ok?
> a) an exception vector(s)
> b) an overlay for a set of device control registers
>
>For (a) you can define a section, and use the linker script to
>perform the locating in Flash. For (b), I've always found it
>nicer to just use a pointer to the peripherals region instead,
>eg.
>
> typedef struct serial {
> int control;
> int status;
> int data;
> } serial_t;
>
> serial_t *com1 = (serial_t *)(SERIAL_BASE_ADDR);
>
> registers are accessed as com1->control = ...
>
>If you use the linker to link this structure over a specific range
>of addresses, then the syntax changes to com1.control = ...
>But you have to do more work with the linker script.
>
>So, perhaps you are trying to implement something the
>difficult way, tell us what you are trying to do.
>
>Cheers,
>Dave
>
>
>
>
>
>
>
>Yahoo! Groups Links
>
>
>
>
>
>
>
>
--
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------2005-11-02 by David Hawkins
Hey Tom,
> >The only time I can ever think of needed to force a
> >particular code at a specific address is;
> >
> Just because you know a couple of things doesn't mean that you
> know it all.
>
Sorry, wasn't trying to sound like I knew it all, on
the contrary, I'm learning too, so wanted to know why,
given that I knew of two possible options.
So, thanks for responding :)
> If you recognized the "AT" directive then you would have
> understood that the question was regard to locating a section
> to a hard address. Typically this is done to describe where
> something such as a binary image produced by something other
> than the compiler. Or, it is done to physically locate entire
> Sections of code into external memory devices.
>
> Ok?
Yep, I understand now that Michel responded with a more detailed
response and showed that he wanted to locate a function at a
specific address. His original email was vague on the 'why',
which was why I wrote my response.
Since you are familiar with linker scripts, perhaps you can answer
a question for me :)
In the LPC2138 manual (lpc213x_um.pdf p227) there are comments
regarding the assumed use of RAM by the on-chip functions;
RAM used by ISP command handler
ISP commands use on-chip RAM from 0x4000 0120 to 0x4000 01FF.
The user could use this area, but the contents may be lost
upon reset. Flash programming commands use the top 32 bytes of
on-chip RAM. The stack is located at RAM top - 32. The
maximum stack usage is 256 bytes and it grows downwards.
RAM used by IAP command handler
Flash programming commands use the top 32 bytes of on-chip RAM.
The maximum stack usage in the user allocated stack space is
128 bytes and it grows downwards.
RAM used by RealMonitor
The RealMonitor uses on-chip RAM from 0x4000 0040 to 0x4000 011F.
The user could use this area if RealMonitor based debug is not
required. The Flash boot loader does not initialize the stack
for RealMonitor.
If you wanted to enable each of these features, what would be your
recommeded way of dealing with the preassigned blocks of RAM;
a) define multiple memory sections
i.e., instead of the normal
MEMORY
{
flash (rx) : org = 0x00000000, len = 0x00080000
sram (rw) : org = 0x40000000, len = 0x00008000
}
write
MEMORY
{
flash (rx) : org = 0x00000000, len = 0x00080000
/* reserve for real monitor */
sram_rm (rw) : org = 0x40000040, len = 0x000000E0
/* reserve for IAP stack */
sram_isp (rw) : org = 0x40000120, len = 0x000000E0
/* User SRAM */
sram (rw) : org = 0x40000200, len = 0x00008000
}
(actually, I don't think the reserved memory sections even need
to be defined, unless you use them in the SECTIONS area, simply
moving the start of SRAM to 0x40000200 would seem appropriate).
or
b) Keep the first MEMORY sections above, and create dummy sections
in the SECTIONS area and eject them into the sram at the right
spot?
Cheers,
Dave2005-11-02 by Tom Walsh
David Hawkins wrote: >Hey Tom, > > > >>>The only time I can ever think of needed to force a >>>particular code at a specific address is; >>> >>> >>> >>Just because you know a couple of things doesn't mean that you >>know it all. >> >> >> > >Sorry, wasn't trying to sound like I knew it all, on >the contrary, I'm learning too, so wanted to know why, >given that I knew of two possible options. > >So, thanks for responding :) > > > It was my problem, not yours. Thank you anyway. >>If you recognized the "AT" directive then you would have >>understood that the question was regard to locating a section >>to a hard address. Typically this is done to describe where >>something such as a binary image produced by something other >>than the compiler. Or, it is done to physically locate entire >>Sections of code into external memory devices. >> >>Ok? >> >> > >Yep, I understand now that Michel responded with a more detailed >response and showed that he wanted to locate a function at a >specific address. His original email was vague on the 'why', >which was why I wrote my response. > >Since you are familiar with linker scripts, perhaps you can answer >a question for me :) > > > The code examples that you mentioned before are appropriate for the high-level referencing of objects, referencing where they lie in the memory map. Linker scripts are for the physical placement of objects within that memory map, the "ordering" of the memory. IIRC, the "AT" was used by Microsoft in their linkers to describe where fixed sections of memory resided. However, you could not fill that region with code though, it was more of a template, a concept more than physically usefull. While most of the Philips LPC2xxx ARM chips have a simple memory architecture, other ARM systems don't. With "classic" controller systems, you have external RAM, ROM and hardware connected to chip selects. The programmed value of the chip select regions along with the linker script would be how you define where those objects resided and gain access to them. Then you could use the typedef approach to further refine that objects description and assign an address which points to that object in C / Assembler. By use of the linker, you can also describe a region of memory within Flash / RAM as a kind of "hole", or protected area. As in "don't put anything here". Then, using objcopy, you can pull out the individual Sections (.text, .data, etc) from the linked image and put them into seperate files. Then those seperate files can be physically combined (cat'ed together) to build a ROM-able image. We did this with the uClinux kernel, the kernel was ORG'ed to run at 0000h in RAM, and the file system was at the top of the RAM (end). In a case such as that, you could have a huge distance between the RAM memory address and that of the filesystem. The gap between the end of the kernel and start of the filesystem was the Heap. This is what the Absolute Linking with GCC doc described, how to deal with describing how to logically place the two parts into the final image. As the final image was ELF, not BINARY, the hole did not take up space, but we need to get that ELF file into ROM / Compact Flash. This is where objcopy came in. For the LPC2000 series, creating such a "hole" is still an advantage. The LPC2000 will execute code from RAM, you could describe an area of the SRAM which is an area where you could pull executable code in from an MMC / Compact Flash and execute it. For example, if you only need your system configuration menus / user interactive setup code infrequently, why put it in the valuable Flash area. You can simply pull it in from the Flash Drive, execute it, and throw it away when you are done! Again, I apologize for my short temper. :-/ Regards, TomW -- Tom Walsh - WN3L - Embedded Systems Consultant http://openhardware.net, http://cyberiansoftware.com "Windows? No thanks, I have work to do..." ----------------------------------------------------
2005-11-02 by David Hawkins
Hey Tom, > It was my problem, not yours. Thank you anyway. No sweat, glad you are listening in on things and are willing to share. > We did this with the uClinux kernel ... Yeah, I took a look at your the reference you posted on http://openhardware.net. Thanks again, Dave
2005-11-03 by sig5534@hotmail.com
I do this a lot when I want to lock variables in RAM across different firmware versions. That way the data structures are at the same place no matter if the firmware gets updated. That is important for some of my code where I am doing a lot of IAP between ROM and RAM. All I do is define a type, then a pointer for that type, and then assign a hard adr value to that pointer. Easy. Chris.
----- Original Message -----
From: Michel Kuenemann
To: lpc2000@yahoogroups.com
Sent: Tuesday, November 01, 2005 10:17 AM
Subject: [lpc2000] How to specify the location of an object in memory (GNU)
Dear LPC2000 Group,
I am using the KEIL IDE for ARM7 processors with the GNU Cygnus compiler on
a LPC2106 target. My
problem is that I cannot find in the documentation how to tell the compiler
to locate an object at a specified place (somwhere in flash memory, for
instance).
In another IDE I am using, I would write :
at 0x00016000 int base;
Can someone help me ?
Thank you.
Michel Kuenemann
KMS - France
SPONSORED LINKS Microprocessor Microcontrollers Pic microcontrollers
8051 microprocessor
------------------------------------------------------------------------------
YAHOO! GROUPS LINKS
a.. Visit your group "lpc2000" on the web.
b.. To unsubscribe from this group, send an email to:
lpc2000-unsubscribe@yahoogroups.com
c.. Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
------------------------------------------------------------------------------
[Non-text portions of this message have been removed]