I am trying to force the linker (ld from XC32) to place the same executable code in two different sections of flash.
The application is so that the code can be run as a standalone application, and also so that the reset vector can be overridden by a bootloader which can then branch to a pseudo reset vector.
The relevant sections of my linker script are
MEMORY
{
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x480
bootload_boot_mem : ORIGIN = 0x9D1F0000, LENGTH = 0x480
}
SECTIONS
{
.reset 0xBFC00000 :
{
KEEP(*(.reset))
} > kseg1_boot_mem
.bootloadreset 0x9D1F0000 :
{
KEEP(*(.reset))
} > bootload_boot_mem
}
Using this the area at 0xBFC00000 is populated as expected, but nothing gets placed at 0x9D1F0000. I have tried passing the option --no-gc-sections to the linker but it doesn't seem to make any difference.
My question is: Is it possible to force the linker to put the same code into 2 different sections, and how to do so?
Whether or not it was the right way to solve this problem, the solution I came up with was:
Move the start up code to the area at 0x9D1F0000, by removing the KEEP(*(.reset)) block from the .reset section. Place an asm function at the reset address which jumps to the relocated start up code. Allow the bootloader to overwrite the asm function as it will then branch to the start up code when it's finished its work.
I solved it by adding new memory region
MEMORY
{
virtual_boot : ORIGIN = 0xBFC00000, LENGTH = 0x200
.
.
.
}
then in section I added
SECTIONS
{
.virtualboot :
{
/*KEEP(*(.virtualboot))*/
LONG(0x08000000 | ((_RESET_ADDR & 0x1FFFFFFF) >> 2));
LONG(0x00);
} > virtual_boot
.
.
.
}
_RESET_ADDR should be defined earlier, in my code it was
_RESET_ADDR = (0x9D006000 + 0x1000);
by this my code become able to run on the MCU with/without bootloader
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With