You asked if you should modify or create a new linker script. I would requirement that you modify the exciting linker script. I find them from time to time quite extensive. Why throw away what is already there while modifying it is only a few lines.
Some very common cases for micro controllers to change the linker script are:
- Adding a bootloader in the first flash sector while the actual program starts in a higher sector.
- Adding a sector dedicated to storing data generated by the application.
- Using a dedicated sector for configuration parameters.
Lets use the first as an example on how to write to firmware to different flash sectors. Important to know is that for this example the bootloader and the actual application are two separate projects each with their own compilation configuration or makefile. Each project also has its own linker script. Below part of both files is listed:
The bootloader:
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
}
The application:
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x0800C000, LENGTH = (1M - 16K)
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
}
Please not the differences in the definition of the FLASH. The bootloader flash start at the default. The size allocated for the bootloader is 16K. Important to note is that the total flash size of the example chip is 1M. This is seen in the size of the flash of the application project. But we do not allow the full 1M for the application as of course we need to reduce it by the size allocated for the bootloader. You can also see it does not start at the same address. It has an offset of 0xC000 which amounts for the 16k.
Before you can run and debug the application code you have to do two more things:
- Define the vector table offset of your code. This is required for the compiler and linker to know where the code is located in memory. This is where my knowledge of this part is lacking a bit so anyone who knows please elaborate.
- If you would like to debug your application you also have to tell your debugger where to start. Atollic does this via a linker script. From what I remember from a few years back Atmel Studio has an option in the programming window where you can set the offset.
One final note: when you do something link this it is best to stick to the flash sectors of the chip. Often you can only delete a whole sector. Placing your next part of the code at the start of the next sector makes live easier.
The given examples are based on a linker file generated by Atollic TrueSTUDIO for STM32 for a STM32F4xx chip. Compilation is done using ARM gcc toolchain.