I've made some progress on getting a GCC and Newlib built to support
the PXA320. In the process, I've taken some steps that seem to be
interfering with the "normal" operation of gcc. For instance, I have
my own linker script, and my own start file.
As I understand it, gcc automatically calls the __main() that calls
the C++ constructor code generated by collect2 (http://gcc.gnu.org/
onlinedocs/gccint/Collect2.html). However, while global constructor
code is being generated, it's not being called in my situation. I've
been able to directly call the routine generated, but this is
suboptimal because it's named after the name of the variable being
constructed.
For example, I build with the following:
----------------------------------
arm-elf-gcc -v -Wl,-Map,mapfile.txt -nostartfiles -Xlinker --
script=link.lds -o h.elf obj/start.o obj/glue.o obj/Graphics.o obj/
Particle.o obj/Util.o obj/lcd.o obj/main.o
Using built-in specs.
Target: arm-elf
Configured with: ../configure --prefix=/usr/local/arm3 --target=arm-
elf --with-newlib --with-cpu=xscale --enable-languages=c,c++
Thread model: single
gcc version 4.2.1
/usr/local/arm3/libexec/gcc/arm-elf/4.2.1/collect2 -X -o h.elf -L/
usr/local/arm3/lib/gcc/arm-elf/4.2.1 -L/usr/local/arm3/lib/gcc/arm-
elf/4.2.1/../../../../arm-elf/lib -Map mapfile.txt --script=link.lds
obj/start.o obj/glue.o obj/Graphics.o obj/Particle.o obj/Util.o obj/
lcd.o obj/main.o --start-group -lgcc -lc --end-group
----------------------------------
In main.cc, I have some code like the following:
----------------------------------
const UInt16 kNumParticles = 100;
Particle gParticles[kNumParticles];
extern "C"
void _GLOBAL__I_gParticles(void);
int
main(void)
{
// Initialize static constructors. Not sure why
// __main() isn't getting called...
_GLOBAL__I_gParticles();
.
.
.
}
----------------------------------
As is, the code works fine, and the Particle objects in the array
gParticles[] get constructed. But I shouldn't have to explicitly call
_GLOBAL__I_gParticles(), and I'm wondering what I did to break this.
My guess would be that my start.S file should be calling __main(),
but near as I can tell, __main() is not even getting generated. Also,
the collect2 docs say that if main is compiled by GCC, then it will
automatically call __main().
I tried letting GCC put its own start file in there, but this caused
the boot loader to complain that "the kernel returned." The boot
loader is expecting to launch a Linux kernel, and so I have a start.S
that looks like this:
----------------------------------
.text
.globl _start
_start:
/* this is a hack to be able to chain load diag from
* bootldr. bootldr checks if it can find the linux zImage
* magic value at the ninth word of an image, so we just put
* it there.
*/
b do_bss
.org (_start + 9 * 4)
/*# .word 0x016f2818*/
.word 0xDEADBEEF
do_bss:
/* clear the BSS section */
ldr r1, bss_start
ldr r0, bss_end
sub r0, r0, r1
/* r1 = start address */
/* r0 = #number of bytes */
mov r2, #0
clear_bss:
stmia r1!, {r2}
subs r0, r0, #4
bne clear_bss
/* setup the stack pointer */
ldr r0, stack_end
sub sp, r0, #4
loop:
bl main
/* if main ever returns we just call it again */
b _start
ldmfd sp, {fp, sp, pc}
.global data_start;
data_start: .word __data_start_foo
bss_start: .word __bss_start
bss_end: .word __bss_end
stack_end: .word __stack_end
----------------------------------
Any suggestions/clarification? Thanks!
--
Rick