incrediball wrote on Tuesday, April 07, 2009:
The problem with a bootloader is that it defines the default vector table and you would need to get the bootloader interrupt handling to relay all the interrupts through to the main program. This is messy, may not support all of the interrupt types (e.g. SWI in your case) and adds latency to the interrupt handling. To use get around this problem modify your main program so:
1. Define your ROM or FLASH sector at 0x00100000 plus the size of the bootloader sector. For example if you reserve 4K for the bootloader (this corresponds to the first lockable page on the AT91SAM7S64) then define it at 0x00101000.
Note that the flash memory on the AT91SAM7S is really located at 0x00100000 so doing this is not a trick. This memory is only mirrored to 0x00000000 by default.
2. Locate your vector table at 0x00200000, for example:
/* Exception vectors located at 0x00200000. These are re-mapped to 0x00000000 by the re-map command */
/* Note that undf, pabt, dabt just execute a null loop. */
b . /* 0x00 reset - not used since the processor has already reset when it re-maps the memory */
b . /* 0x04 undef */
ldr pc, _swi_ram /* 0x08 swi */
b . /* 0x0C pabt */
b . /* 0x10 dabt */
nop /* 0x14 rsvd */
ldr pc, [pc,#-0xF20] /* 0x18 irq - load PC with the interrupt vector in AT91C_BASE_AIC->AIC_IVR */
ldr pc, [pc,#-0xF20] /* 0x1c fiq - load PC with the interrupt vector in AT91C_BASE_AIC->AIC_FVR */
_swi_ram: .word vPortYieldProcessor
You will need to modify your linker script to tell the linker to put the vectors section first in the RAM.
3. Perform a remap command as soon as the main program starts up. This mirrors the vector table defined at 0x00200000 to 0x00000000 thus replacing the vector table defined by the bootloader.