AnsweredAssumed Answered

How to relocate code in flash to a non-standard starting point?

Question asked by Robert Poor on Sep 18, 2017
Latest reply on Sep 19, 2017 by Alice_Yang

General question: What's the right way to relocate the code in a project so as to leave room in "low flash" for a flash-based bootloader?  And how do I tell KDS that the code has been relocated?

Details:

 

I have two simple "blink the LED" projects for a FRDM-KL27Z that are identical in every way except for the .ld map.

blinky-0000

The "standard" blinky-0000 uses the default .ld map as created by the KDS 2.x project builder, so the MKL27Z64xxx4_flash.ld file contains:

/* Specify the memory areas */
MEMORY
{
  m_interrupts          (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000200
  m_flash_config        (RX)  : ORIGIN = 0x00000400, LENGTH = 0x00000010
  m_text                (RX)  : ORIGIN = 0x00000410, LENGTH = 0x0000FBF0
  m_usb_sram            (RW)  : ORIGIN = 0x040FE000, LENGTH = 0x00000200
  m_data                (RW)  : ORIGIN = 0x1FFFF000, LENGTH = 0x00004000
}

And it loads (via Segger J-Link / JTAG) and executes properly.  Just to double check, I disassembled 0x0410 and found the expected code:

__do_global_dtors_aux:
00000410: push {r4, lr}
00000412: ldr r4, [pc, #24] ; (0x42c <__do_global_dtors_aux+28>)
00000414: ldrb r3, [r4, #0]
00000416: cmp r3, #0
00000418: bne.n 0x42a <__do_global_dtors_aux+26>
0000041a: ldr r3, [pc, #20] ; (0x430 <__do_global_dtors_aux+32>)
... etc

blinky-8000

I also created a blinky-8000 project, where the *only* difference is that I modified the memory map to offset each section by 0x8000, so my MKL27Z64xxx4_flash.ld file contains:

/* Specify the memory areas */
MEMORY
{
  m_interrupts          (RX)  : ORIGIN = 0x00008000, LENGTH = 0x00000200
  m_flash_config        (RX)  : ORIGIN = 0x00008400, LENGTH = 0x00000010
  m_text                (RX)  : ORIGIN = 0x00008410, LENGTH = 0x0000FBF0
  m_usb_sram            (RW)  : ORIGIN = 0x040FE000, LENGTH = 0x00000200
  m_data                (RW)  : ORIGIN = 0x1FFFF000, LENGTH = 0x00004000
}

When I load this via the Segger J-Link and attempt to run it, it ends up running the original blinky-0000 code.  And it doesn't know how to find the source code associated with the current PC, which isn't surprising since it's running at the "low" pc values.

But I do know the blinky-8000 code HAS been loaded, since I can disassemble it at the expected 0x8410 address:

__do_global_dtors_aux:
00008410: push {r4, lr}
00008412: ldr r4, [pc, #24] ; (0x842c <__do_global_dtors_aux+28>)
00008414: ldrb r3, [r4, #0]
00008416: cmp r3, #0
00008418: bne.n 0x842a <__do_global_dtors_aux+26>
0000841a: ldr r3, [pc, #20] ; (0x8430 <__do_global_dtors_aux+32>)
... etc

 

In the Debug Configurations, I set ["Set program counter at (hex):] to 8410, but that didn't seem have any effect.  (I also tried setting the [Executable offset (hex):] to 8000, but that had no apparent effect either.)

Debugger Configuration

In conclusion:

I can summarize my questions as follows:

  • Is simply adding an offset (e.g. 0x8000) to the memory sections in the .ld file necessary and sufficient for relocating the code, e.g. above a piece of flash that I wish to preserve?
  • How do I arrange things so the code starts at 0x8410 rather than at 0x0410?
  • How do I tell KDS_v3 how to find the relocated code?

 

Project files attached...

Original Attachment has been moved to: blinky-8000.zip

Original Attachment has been moved to: blinky-0000.zip

Outcomes