I've been
struggling with (.data), (.bss) and (.rodata) sections. At the end of this
message, I have some issues I couldn't figure out. Any help will be greatly
appreciated.
I did some testing and
here are the results. Hope this information is helpful to anybody
else.
Some ELF sections
definitions (from targeting manual):
========================================================
(.bss) => segment for uninitialized data. The
stationery init code zeroes this area at startup.
(.data) => segment for initialized data here by
default.
(.rodata) => segment for constant data, if the
project has the write constant data to .rodata section checkbox enabled in
target settings.
By default,
zero-initialized data is put into the .bss section by the compiler (zeroed by
INIT code). This behavior can be overriden by using the #pragma
explicit_zero_data
Results compiling a C
file, using Codewarrior 5.1:
========================================================
(comments indicate
where the variable/constant was placed, taken from ELF symbol
table)
// **** initialized
stuff ****
const unsigned int
VAR1[3] = { 0x110A, 0x110B, 0x110C}; //
.rodata
const
int VAR2[3] = { 0x220A, 0x220B, 0x220C}; //
.rodata
unsigned int
VAR3[3] = { 0x330A, 0x330B, 0x330C}; //
.data
int VAR4[3] = { 0x440A, 0x440B, 0x440C}; //
.data
const unsigned int
VAR5 = 0x5555; //
.rodata
const
int VAR6 = 0x6666;
// .rodata
unsigned int
VAR7 = 0x7777; //
.data
int VAR8 = 0x8888;
// .data
// ****
zero-initialized stuff ****
const unsigned int
VAR9[3] = { 0x0000, 0x0000, 0x0000}; //
.rodata
const
int VAR10[3] = { 0x0000, 0x0000, 0x0000}; //
.rodata
unsigned int VAR11[3] = {
0x0000, 0x0000, 0x0000}; // .bss
int VAR12[3] = { 0x0000, 0x0000, 0x0000}; //
.bss
const unsigned int
VAR13 = 0x0000; //
.rodata
const
int VAR14 = 0x0000;
// .rodata
unsigned int
VAR15 = 0x0000; //
.bss
int VAR16 = 0x0000;
// .bss
// **** uninitialized
stuff ****
unsigned int VAR17[3]
; // .bss
int VAR18[3] ; // .bss
unsigned int
VAR19 ; //
.bss
int VAR20 ; //
.bss
Observations:
========================================================
Constants: as expected,
all of them are placed into (.rodata), even zero-initialized. These are to be
loaded with application.
Variables: as expected,
initialized stuff goes to (.data) and will be loaded to DSP with application.
Zero-initialized stuff goes to (.bss) and will not be loaded with application.
Instead, they'll be zeroed by DSP initialize code. Uninitialized variables
also go to (.bss).
Stuff that I
couldn't figure out:
========================================================
Where and how to place
these sections in memory?
For (.rodata) sections,
I would place them in (.x_flash_ROM). They are supposed to be constants, they
should be downloaded with application and remain there when power goes off.
Right?
For (.bss) sections, I
would place them in (.x_RAM). They are supposed to be R/W and will be
initialized after /RESET. Therefore, uninitialized data and zero-initialized
data should go here. Right?
For (.data)... I read a
thousand times "ROM to RAM Copying" in targeting. Still can't figure out.
Here's my thinking: (.data) holds initialized variables. I would want them
to be downloaded to ROM (to save them when power goes off) and copied to RAM
when using them (to be able to R/W).
Questions:
a) Why "ROM to RAM
Copying" specifies to move (.data) to .p_ROM and not .x_ROM ? Why not copying
from .xROM to .xRAM ?
b) "Targeting"
specifies this LCF:
----------------------------
MEMORY
{
.text (RWX)
: ORIGIN = 0x8000, LENGTH = 0x0 # code
(P)
.data
(RW) : ORIGIN = 0x3000, LENGTH = 0x0 # data
(X)-> RAM
}
SECTIONS{
F__ROM_Address =
0x1000; # ROM Starting
Address
.main_application :
{
# .text sections
*(.text)
} >
.text
.data : AT(
F__ROM_Address ) # Start data at 0x1000 ->
ROM
{
# .data sections
F_Begin_Data =
.; # Get start
location for RAM
*(.data) #
Write data to the section (ROM)
F_End_Data =
.; #
Get end location for RAM
# .bss sections
* (.bss)
} >
.data
}
----------------------------
b.1) "F__ROM_Address =
0x1000" does not specify if it is .xROM, .xRAM, etc. What does "AT(
F__ROM_Address )" mean ? Shouldn't it be like "F_ROM_Address = .;" inside a
(.text) section?
b.2) I assume that AT
means "put the following sections in F__ROM_Address, but declare them as .data
in .xRAM. Is this so?
b.3) In my C file, I
should do a :
memcpy( (unsigned long *)&__Begin_Data,
(const
unsigned long *)&__ROMAddress,
dataLen
);
But how to tell the
compiler that one address corresponds to .pROM and the other to .xRAM? is it
embedded in __Begin_Data and __ROMAddress ?
I apologize for the
extended size of this post. Any help on this will be greatly appreciated.
It's 1:30am and I should be sleeping by now, but CodeWarrior has been
keeping me awake till late with this mess... I hope I can solve this soon and
get my life back to normal :)
Regards,
Mariano
Filippa
|