avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] gcc: putting a variable in a certain section


From: Tyler Hall
Subject: Re: [avr-gcc-list] gcc: putting a variable in a certain section
Date: Mon, 28 Apr 2003 00:15:24 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.0.2) Gecko/20021216

Torsten Mohr wrote:

Hi,

But i still wonder:

int __attribute__((section("ramsection"))) ramvalue = 0xdead;
                                                    ^^^^^^

"ramvalue" is located in RAM, but where is the "0xdead"?
Where you requested it to be: in section "mysection" of your ELF
file.  It's your responsibility to extract it from there.

hmm, this is not yet what i'd expect.  Maybe i'm wrong, but:
When i put a variable WITH initial value into RAM:

int abc = 0x1234;

Then there should be TWO sections involved, one in RAM where
2 bytes for the int are reserved and another section in ROM
somewhere, where the initial value is stored (also two bytes).
The startup code should then copy this section into RAM, so
all values WITH initial values get their initial values.

But how is this done, if i place a variable WITH initial
value in an own section?


Best regards,
Torsten.


_______________________________________________
avr-gcc-list mailing list
address@hidden
http://www.avr1.org/mailman/listinfo/avr-gcc-list

You're getting two realms confused here: ELF sections and physical memory spaces. What defines which ELF sections go in which physical memory spaces is the linker script. You may already know some of this stuff below, but I'll mention it for the sake of other embedded system newbies...

The default linker scripts for the avr5 class define 3 memory spaces:
MEMORY
{
 text   (rx)   : ORIGIN = 0, LENGTH = 128K
 data   (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
 eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
}

and a whole lot of possible sections which may or may not appear in a given object file, including (I've trimmed this to show relevant stuff):
SECTIONS
{
 .text :
 {
   *(.vectors)
   *(.vectors.*)
   *(.progmem*)
   *(.text)
   *(.text.*)
 } > text
 .data : AT (ADDR (.text) + SIZEOF (.text))
 {
   *(.data)
 }  > data
 .eeprom  :  AT (ADDR (.text) + SIZEOF (.text) + SIZEOF (.data))
 {
   *(.eeprom*)
 }  > eeprom
}

So if you explicitly assign a variable to be in "ramsection" it actually won't end up in your target because the linker script doesn't know what to do with that name, especially since it doesn't match any of the wild-card section names already defined in the linker script. You should read the info pages on gnu's ld, but basically the above states in english that:
- There are 3 memory spaces,
- The "text" memory space (not to be confused with the .text section) is the name of the VIRTUAL memory region starting at 0, through the next 128k bytes - The "data" memory space (not to be confused with the .data section) is the name of the VIRTUAL memory region 0x800060, through the next 0xffa0 bytes - The "eeprom" memory space (again, not the .eeprom section) is the name of VIRTUAL memory region 0x810000, through the next 64 k bytes

Then it states which sections should go into what memory spaces in which order, AND at the same time also declare a different PHYSICAL temporary address if need be: - The .text section and friends go into the "text" memory space, leaving the physical and virtual addresses equal (both starting at 0) - The .data section goes into the "data" memory space, but the physical address is set to start at the first byte after the end of the .text section. - The .eeprom section and friends go into the "eeprom" memory space, but the physical address is set to start at the first byte after the end of the .data section.

The physical addresses end up all clumped together so you can "export" the whole thing to one image chunk to be burned to flash. There are are global variables set by the linker (told by the linker script, parts which I didn't copy & paste) that hold the physical addresses of each memory-space-image. The crt (C RunTime) routine, which comes with avr-libc, uses these to global variables to copy the image from flash to the target memory space. Technically this could mean that the crt copies the "data" image to internal RAM AND the "eeprom" image to the internal EEPROM, but I don't think it's currently implemented that way since the EEPROM can be programmed separately by the STK board or JTAG ICE.

Once the "data" image has been copied (say from starting at flash addr 0x14C over to RAM addr 0x000), only THEN is the data in alignment with what the code assumes (still sitting in the "text" image at flash addr 0x000).

So in short, a normal variable with an initial value will have that initial value defined in the .data section. The linker script keeps all the sections separate in an ELF file, but when converted to a binary or hex file, they are organized according to the physical addresses and then dumped to that file, which will be all programmed to flash (ROM). The code that was dumped in the process has hard-coded physical address of the start of data image and copies the image to RAM before executing anything else (like main()).

If you want a section called "ramsection" with initial values put there, the C code:

int __attribute__((section("ramsection"))) ramvalue = 0xdead;

will do just that. Assuming nothing else is put into "ramsection", you could use avr-objdump on "ramsection" and see that the word at address 0 would be 0xdead. The code that uses the variable ramvalue will assume that the variable is located at address 0 of section "ramsection".

If you want that section to appear in RAM, add to the linker script a line that indicates such. You'll have a choice of whether to put "ramsection" in front of the normal .data section or after it. This will have the added bonus of relocating all references to data inside section "ramsection" to some offset into section ".data", which is what you'll want if you want your code to find your variable ramvalue in RAM.

Tyler




reply via email to

[Prev in Thread] Current Thread [Next in Thread]