Thank you, LPCX support, for your reply. Your suggestion, however, that we use the GUI flash programmer to program, along with the attach-only debug methodology, seemed like it would make the edit/debug cycle quite cumbersome. I figured there had to be a simpler way.
I found one.
Since I could not find any evidence of how to accomplish multiple regions with 0x0 base linking, and in case this is helpful to someone else, here's what we did:
1. As LPCX support suggested, in the memory configuration dialog, I createda flash memory location at 0x0 with the length required for the firmware. We use a length of 0x40000 which is 256kB. This should *not* be the first flash memory area listed (as the first location will be the load address). We named the new segment ShadowFlash.
2. We modified the link_template.ld file with a simple change. At the end of any .text section--after the close bracket--there normally is an instruction to position .text in the first firmware bank that looks like this: >${CODE}. Change that line to be: >ShadowFlash AT>${CODE}. This change instructs the linker to compile the code in the ShadowRam region (0x0), but load it in the ${CODE} region. The macro ${CODE} resolves to the name of the first flash bank in the memory configuration dialog.
3. We used the M4MEMMAP register to set the base address of where the code will load, which is the first flash memory area in the memory configuration dialog. M4MEMMAP tells the processor that any addresses referenced from 0 should be mapped to the ${CODE} region. However, there's a gotcha here. The M4MEMMAP register does not add a specified memory location to the M4MEMMAP value correctly. It does an XOR instead. To avoid this mapping problem, make sure that the entire region you hope to reach is represented by zeros in the ${CODE} region base address. For example, using 0x14030000 will not work for more than one 64k block, but 0x14080000 will work for several 64k blocks. In other words, the memory map register needs to be aligned to the nearest power of 2 that is greater than or equal to the size of the region you want to map. I didn't design it, but that's how it works.
4. In the boot loader, after setting the M4MEMMAP register, do not immediately jump to a location in the new memory area. Apparently it takes a beat or two before the M4MEMMAP register gets correctly set. We defined the M4MEMMAP as volatile which may help, then we added a loop to read back the value until we were sure the value was set correctly, before jumping into the newly mapped space. Again, I didn't design it, but much experimentation and debugging led to the conclusion.
Now our code can work in either our A region or B region. It only debugs in the A region (which is ok with us), but the best part is that it loads correctly in the debugger just as before.
Thanks,