Robert,
From your update 2 it looks like you're really close to solving your issue, you're only missing an interrupt clear inside of your timer interrupt handler. Adding this line:
PIT_ClearStatusFlags(PIT, 0, kPIT_TimerFlag);
You're seeing the CPU continually service the interrupt, since it's never cleared. It probably looks like it's running through the code properly because of the debugger delays, but it's really never able to go and do anything other than service the interrupt once it has been set by the PIT.
Now a little bit of background information on how you could have approached the use of interrupts in SDK 2.0 differently (hopefully a little easier as well).
Each of the interrupt functions in SDK 2.0 are defined with the 'weak' attribute. From gcc.gnu.org,
weak
The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions which can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker.
This means that in order to override the weak symbol, all you need to do is define the interrupt symbol in your own code. Interrupt symbols can be found in startup_<soc_name>.S. Choosing this route eliminates the need for the special linker directives as well as having to install the interrupt from application code; there's nothing to install when you're using the default symbol in the vector table. In my test, my interrupt handler looks like:
void PIT0_IRQHandler() {
PIT_StopTimer(PIT, 0);
PIT_ClearStatusFlags(PIT, 0, kPIT_TimerFlag);
timerWentOff = true;
}