Hi. Some background:
I'm using GCC 4.2.x to target an XScale (ARM) processor. I don't get
the benefit of an OS (FAA certification requirements), so I have to
write everything myself.
As I understand it (I'm 95% sure of most of this), on this processor
interrupts are handled with an exception vector table at 0x00000000
or 0xFFFF0000 (as opposed to say, the Atmel ARM7 which lets you set
the address of exception vectors via hardware registers). What makes
things difficult is that, in absence of MMU remapping, there is no
memory at these regions (all RAM exists in the middle of the address
space).
So, I enable the MMU and remaps some arbitrary 1 MB page of RAM down
to 0x00000000, and now I'm able to write something into the exception
vector table.
Now I'm trying to figure out how to get GCC and the linker to create
a vector table, and code to (long) jump to a set of C routines for
handling the interrupts. Since it has to jump much farther than the
32MB of an ARM branch instruction, it needs to generate long jumps. I
tried writing something like this:
vectors:
b ResetHandlerGlue
b UndefinedHandlerGlue
b SWIHandlerGlue
b PrefetchAbortHandlerGlue
b DataAbortHandlerGlue
nop
b IRQHandlerGlue
b FIQHandlerGlue
ResetHandlerGlue:
ldr r0,=ResetHandler
mov pc,r0
99: b 99b // Stop if reset ever exits.
UndefinedHandlerGlue:
ldr r0,=UndefinedHandler
mov pc,r0
The intent is to copy that code to 0x00000000, but I can't get GCC to
org it to 0 without complaining.
If I include this with the rest of my code in the liner script, it
ends up generating pc-relative loads of the address of ResetHandler()
and UndefinedHandler(), which won't work when the code is copied to
0x0. If I try to separate it out, like this:
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
vectorsStart = .;
KEEP (obj/vectors.o(.text));
vectorsEnd = .;
}
. = 0x80008000;
. = ALIGN(4);
.text :
{
obj/start.o(.text);
src/Interrupts.o(.text);
}
.
.
.
}
I get errors like:
obj/start.o: In function `loop':
(.text+0x4c): relocation truncated to fit: R_ARM_PC24 against symbol
`_init' defined in .init section in /usr/local/arm3/lib/gcc/arm-elf/
4.2.1/crti.o
obj/start.o: In function `loop':
(.text+0x54): relocation truncated to fit: R_ARM_PC24 against symbol
`_fini' defined in .fini section in /usr/local/arm3/lib/gcc/arm-elf/
4.2.1/crti.o
/usr/local/arm3/lib/gcc/arm-elf/4.2.1/crtbegin.o:(.fini+0x0):
relocation truncated to fit: R_ARM_PC24 against `__do_global_dtors_aux'
/usr/local/arm3/lib/gcc/arm-elf/4.2.1/crtbegin.o:(.init+0x0):
relocation truncated to fit: R_ARM_PC24 against `frame_dummy'
/usr/local/arm3/lib/gcc/arm-elf/4.2.1/crtend.o:(.init+0x0):
relocation truncated to fit: R_ARM_PC24 against `__do_global_ctors_aux'
I feel like I'm close to getting it to work. I just have to figure
out how to get GCC/GAS to emit long-jump code in the glue routines.
Any suggestions? Thanks!
--
Rick