Anton Stafeyev
Anton Stafeyev

Reputation: 831

GNU linker, different adressing for same memory region

So i have a simple linker script for my stm32f7 mcu

MEMORY{
    ROM_AXIM (rx) : ORIGIN = 0x08000000, LENGTH = 1M
    ROM_ITCM (rx) : ORIGIN = 0x00200000, LENGTH = 1M
    RAM_ITCM (rwx): ORIGIN = 0x00000000, LENGTH = 16K
    RAM_DTCM (rwx): ORIGIN = 0x20000000, LENGTH = 64K
    SRAM     (rwx): ORIGIN = 0x20010000, LENGTH = 240K
    SRAM2    (rwx): ORIGIN = 0x2004C000, LENGTH = 16K
}

_estack = LENGTH(RAM_DTCM) + ORIGIN(RAM_DTCM);

SECTIONS{
    .isr_vector : { 
        KEEP(*(.isr_vector))
    } /* Placed at 0x0 */

    .text : {
        . = ALIGN(4);
        *(.text)
    } >ROM_ITCM

    .data : {
        . = ALIGN(4);   
        _sdata = .;
        *(.data)
        . = ALIGN(4);
        _sdata = .;
    } >SRAM2 AT>ROM_AXIM

    .bss : {
        . = ALIGN(4);
        _sbss = .;
        *(.bss)
        . = ALIGN(4);
        _ebss = .;
    } >SRAM2
}

The idea is to place text section to ROM_ITCM because instruction fetching is accelerated with ART accelerator. But the problem is that ROM_AXIM and ROM_ITCM is the same flash storage. How to tell linker that is physically same storage but accessed on separate buses. So it links like it is two separate buses, but the text section should actually follow .isr_vector immediately in memory and offset is taken into account

For example, here is my bin file that will go to flash:

00000000  00 00 01 20 01 00 20 00  00 00 00 00 00 00 00 00  |... .. .........|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00200000  00 20 70 47                                       |. pG|
00200004

As you can see a lot flash is wasted and it ill try to write this bin beyond flash boundary as well.

VS:

00000000  00 00 01 20 09 00 00 08  00 20 70 47              
0000000c

this hexdump, is what i am looking for but, as you can see Reset_Handler has address of AXIM bus. What i want to do is by using the linker script provided above to get an output like this:

00000000  00 00 01 20 09 00 20 00  00 20 70 47              
0000000c 

The difference here is that it will use 0x00200008 to look for my reset handler.

What i have tried so far:

.text : {
        . = ALIGN(4);
        *(.text)
    } >ROM_ITCM AT>ROM_AXIM

This one would work, but the problem is that it will give this output

00000000  00 00 01 20 01 00 20 00  00 20 70 47              |... .. .. pG|
0000000c

which will load instruction at 0x00200000 and by doing that it will load first entry of vector table (stack pointer) as an instruction

Upvotes: 1

Views: 219

Answers (1)

Anton Stafeyev
Anton Stafeyev

Reputation: 831

I managed to solve a problem by consulting a gnu linker page. What i did was to specify runtime offset of a section like this.

.text (0x00200000 + SIZEOF(.isr_vector)): {
        . = ALIGN(4);
        *(.text)
    } AT>ROM_AXIM

What it does is:

  • .text (0x00200000 + SIZEOF(.isr_vector)) specify run-time address with an offset of vector table size. my pointers are now resolved correctly
  • AT>ROM_AXIM places the code right after vector table which produced the offset in first place. and above line fixes it.
  • -

Upvotes: 1

Related Questions