I made an ld script with the following memory layout:
MEMORY
{
FLASH (rx) : ORIGIN = 0x00027000, LENGTH = 0xC8000
RAM (rwx) : ORIGIN = 0x20003FC0, LENGTH = 0x3B040
RRAM (rwx) : ORIGIN = 0x2000F000, LENGTH = 0x01000
}
As you can see, the RRAM (from 0x2000F000 to 0x2000FFFF) portion overlaps with the RAM portion (from 0x20003FC0 to 0x2002FFF). The code compiles and links with no warnings or errors.
My question is: during normal code execution,.will the system still be able to use the memory from 0x2001000 up to 0x2002FFF? Or does this unusual layout stop the code from using anything after the end of RRAM (unless explicitly allocated to an address)?
This is my linker file memory definition (Cortex M4 MCU with flash memory starting at 0x0 address):
MEMORY
{
m_interrupts (RX) : ORIGIN = 0x0000A000, LENGTH = 0x00000410
m_text (RX) : ORIGIN = 0x0000A410, LENGTH = 0x00050BF0
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x0001F000
m_data_2 (RW) : ORIGIN = 0x2000F000, LENGTH = 0x00001000
}
I want to offset my flash from 0x0 to 0xA000 to keep the beginning of the flash clean.
However, when I generate my output (bin) file for my project, I can see the beginning of the flash is still occupied by some data. From .map file I think this is .ARM.attributes, .debug_info, .debug_abbrev, etc. I don't know what it is, but I want the beginning of my flash to be clean, not programmed by anything. How to remove these data from my output bin file or how to move this data to the end of the output bin file?
In some header I've got FLASH_BASE and FLASH_SIZE makro and I would like to use them in linker script. I have tried something like this:
// main.c
long CURRENT_FLASH_START = FLASH_BASE + FLASH_SIZE / 2;
int main(void) {
return 0;
}
// s_FLASH.ld
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 16K
FLASH (rx) : ORIGIN = CURRENT_FLASH_START, LENGTH = 256K
}
But in map file I see that place for code in flash starts at address 0. Is there any possibilty to use variable from makro (from .h file) in linker script file? I use Ac6 STM32 MCU GCC with Gnu Make builder.
I'm writing bare-metal code for a microcontroller (MSP430 series) using the GCC/binutils toolchain and I'd like to use my linker script to fill unused interrupt vectors with the "loop forever" opcode (in dev, in production the "SW reset" opcode). I can't seem to make this happen.
Here's my linker script (or the relevant sections):
MEMORY {
SFR : ORIGIN = 0x0000, LENGTH = 0x0010 /* END=0x0010, size 16 */
PERIPHERAL_8BIT : ORIGIN = 0x0010, LENGTH = 0x00F0 /* END=0x0100, size 240 */
PERIPHERAL_16BIT : ORIGIN = 0x0100, LENGTH = 0x0100 /* END=0x0200, size 256 */
RAM : ORIGIN = 0x1C00, LENGTH = 0x0800 /* END=0x23FF, size 2048 */
INFOMEM : ORIGIN = 0x1800, LENGTH = 0x0200 /* END=0x19FF, size 512 as 4 128-byte segments */
INFOA : ORIGIN = 0x1980, LENGTH = 0x0080 /* END=0x19FF, size 128 */
INFOB : ORIGIN = 0x1900, LENGTH = 0x0080 /* END=0x197F, size 128 */
INFOC : ORIGIN = 0x1880, LENGTH = 0x0080 /* END=0x18FF, size 128 */
INFOD : ORIGIN = 0x1800, LENGTH = 0x0080 /* END=0x187F, size 128 */
FRAM (rxw) : ORIGIN = 0x4400, LENGTH = 0xBB80 /* END=0xFF7F, size 48000 */
VECT1 : ORIGIN = 0xFF90, LENGTH = 0x0002
VECT2 : ORIGIN = 0xFF92, LENGTH = 0x0002
VECT3 : ORIGIN = 0xFF94, LENGTH = 0x0002
... snip ...
VECT54 : ORIGIN = 0xFFFA, LENGTH = 0x0002
VECT55 : ORIGIN = 0xFFFC, LENGTH = 0x0002
RESETVEC : ORIGIN = 0xFFFE, LENGTH = 0x0002
BSL : ORIGIN = 0x1000, LENGTH = 0x0800
HIFRAM (rxw) : ORIGIN = 0x00010000, LENGTH = 0x00003FFF
}
SECTIONS
{
__interrupt_vector_1 : { KEEP (*(__interrupt_vector_1 )) } > VECT1 =0x3C00
__interrupt_vector_2 : { KEEP (*(__interrupt_vector_2 )) } > VECT2 =0x3C00
__interrupt_vector_3 : { KEEP (*(__interrupt_vector_3 )) } > VECT3 =0x3C00
__interrupt_vector_4 : { KEEP (*(__interrupt_vector_4 )) } > VECT4 =0x3C00
__interrupt_vector_5 : { KEEP (*(__interrupt_vector_5 )) } > VECT5 =0x3C00
__interrupt_vector_6 : { KEEP (*(__interrupt_vector_6 )) } > VECT6 =0x3C00
... snip ...
__interrupt_vector_52 : { KEEP (*(__interrupt_vector_52)) KEEP (*(__interrupt_vector_timer0_b0)) } > VECT52 =0x3C00
__interrupt_vector_53 : { KEEP (*(__interrupt_vector_53)) KEEP (*(__interrupt_vector_comp_e)) } > VECT53 =0x3C00
__interrupt_vector_54 : { KEEP (*(__interrupt_vector_54)) KEEP (*(__interrupt_vector_unmi)) } > VECT54 =0x3C00
__interrupt_vector_55 : { KEEP (*(__interrupt_vector_55)) KEEP (*(__interrupt_vector_sysnmi)) } > VECT55 =0x3C00
__reset_vector :
{
KEEP (*(__interrupt_vector_56))
KEEP (*(__interrupt_vector_reset))
KEEP (*(.resetvec))
} > RESETVEC
... and all the usual stuff, .data, .bss, etc ...
(0x3C00 is the "jump forever" opcode)
This doesn't seem to produce the sections at all if there's not at least one symbol on the input.
I tried messing around with . = .; and similar commands to get the section to be created even when there's nothing in the input sections, which sometimes worked, but I need the sections generated to be type PROGBITS and have the A flag set, otherwise they won't be loaded to the target. None of my attempts managed to produce this configuration.
What can I do to generate a section filled with 0x3C00, which is type PROGBITS and has the A flag set, when there is nothing in the input sections?
Thanks in advance for your help!
Can you use the SHORT(0x3C00) syntax?
__interrupt_vector_1 : { SHORT(0x3C00) } > VECT1
This tells the linker to put two bytes 0x3C,00 into the section named __interrupt_vector_1 which is allocated in memory region VECT1. I don't think you need the KEEP directive anymore either. The name of the section, if not used, can be anything you want too. I usually match my sections to my memory regions in cases like this, e.g.
.vect1 : { SHORT(0x3C00) } >vect1
note the dot on the section name.
Also your VECT1 should be:
VECT1 (x) : ORIGIN = 0xFF90, LENGTH = 0x0002
Because it's executable code.
I've made a bootloader and a windows application which communicate. The windows application sends the hex file (user app with an offset starting at 0x0C008000) to the bootloader which stores it at the address in flash. The data of the hex file is stored at the right address. I've checked it by reading the flash.
The bootloader waits for 3 seconds to receive a sign. If there is no sign received then it willjump to the user app.
The Jump is not working and I dont know why. Bootloader starts at 0x0C000000.
In the linker script of the user app i mapped the memory regions like this (starting at 0x0C008000)
MEMORY
{
FLASH_1_cached(RX) : ORIGIN = 0x08008000, LENGTH = 0xf8000
FLASH_1_uncached(RX) : ORIGIN = 0x0C008000, LENGTH = 0xf8000
PSRAM_1(!RX) : ORIGIN = 0x10000000, LENGTH = 0x10000
DSRAM_1_system(!RX) : ORIGIN = 0x20000000, LENGTH = 0x10000
DSRAM_2_comm(!RX) : ORIGIN = 0x30000000, LENGTH = 0x8000
}
The code of the jump is following
void RunFlash(void)
{
PPB->VTOR = 0x0c008000; // Offset of the Vector
asm("ldr r0, =0x0c008000");
asm("ldr r1, =0xE000ED08");
asm("str r0,[r1]");
asm("ldr sp, [r0], #4");
asm("ldr r15, [R0]");
}
I always get an "No source available for "0x80082b0" error.
Can somebody please help me? Do i need to make additional changes to the linker script? Do i need to change something in the startup code?
I'm using an Infenion XMC4500 and DAVE4 IDE.