Help with long jumps and ARM exception vector

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

 



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


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux