Hey, folks!
I have a bootloader project, where I have all the code in the address space 0x0000-0x3999 and above that is the app space, which we can assume to be empty for now.
What I want to do is start the bootloader (which is flashed to the mcu like usual), make itself copy to another memory space, then jump to the copied code and run from there (and keep running, even if I erase everything in the original bootloader space).
I understand that there are different segments, where 0x0 to 0x399 are vectors, 0x410 to somewhere below 0x4000 is program code and so on.
What I want to do is to start the program in the bootloader space. I compile the project with the -fPIC (position independent code) flag and flash it to the mcu. I also have disabled interrupts (disable_irq()).
During runtime the code in the bootloader space gets copied one to one to the app space, starting at 0x4000.
The next thing is how I jump to the new app. Therefore I have another project, where I have set the segment addresses accordingly (0x4000 for vectors, 0x4410 for m_text, etc.). Then I also flash that program, but to the app space. In my bootloader program I now build a function call to enter the app from the value that is stored at the (app start adress +4), the initial program counter. then I execute that function and now I am in the app. So I know, that this is a way to branch to another application, that is stored in flash besides the bootloader.
But what do I have to change in the vector table of the copied bootloader in the app space so that I can successfully jump there? I tried adding the the app start adress to every vector, except the msp at 0x0 (0x4000 in app space).
I would appreciate any pointers in the right direction and hope that I have formulated my question somewhat understandably.
Cheers,
Michael
Hi
I would expect position independent code to be able to operate as long as you add the 0x4000 offset to the reset vector and interrupt vectors when it is located at 0x4000. However don't forget that you will also need to be able to detect at which area you are operating and set the vector base address to either 0 or 0x4000 too.
Beware that any reset or power cycle that takes place when the flash is erased between 0..0x3fff will cause failure to the board and the need to un-secure the flash again and reprogram with JTAG/SWD/EzPort. The length of time that the 0..0x3fff area is thus left erased should be kept as short as possible to reduce the chance of this happening. The technique would generally be used only in exceptional circumstances (where some bricked products are acceptable) or where users have a programming tool (eg. for firmware enginers or hobby users).
Regards
Mark