Help with long jumps and ARM exception vector

Rick Mann rmann@latencyzero.com
Fri Oct 26 05:48:00 GMT 2007


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



More information about the Gcc-help mailing list