Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force the linker to put the same code in 2 sections

Tags:

linker

ld

pic

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?

like image 364
Colin Avatar asked Oct 30 '22 14:10

Colin


2 Answers

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.

like image 117
Colin Avatar answered Jan 04 '23 14:01

Colin


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

like image 27
Rawad Trablsy Avatar answered Jan 04 '23 15:01

Rawad Trablsy