首页 > 解决方案 > GNU链接器,同一内存区域的不同地址

问题描述

所以我为我的 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
}

这个想法是将文本部分放置到 ROM_ITCM 中,因为使用 ART 加速器可以加速指令获取。但问题是 ROM_AXIM 和 ROM_ITCM 是同一个闪存。如何告诉链接器在物理上是相同的存储但在不同的总线上访问。所以它像两条独立的总线一样链接,但文本部分实际上应该紧跟在内存中的 .isr_vector 之后,并且考虑到偏移量

例如,这是我的 bin 文件,它将转到闪存:

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

正如你所看到的,很多闪存被浪费了,它也会尝试将这个 bin 写入闪存边界之外。

对比:

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

这个 hexdump 是我正在寻找的,但是,正如您所看到的,Reset_Handler 具有 AXIM 总线的地址。我想要做的是使用上面提供的链接器脚本来获得这样的输出:

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

这里的区别在于它将使用 0x00200008 来查找我的重置处理程序。

到目前为止我已经尝试过:

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

这个可以工作,但问题是它会给出这个输出

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

它将在 0x00200000 处加载指令,并通过这样做将向量表的第一个条目(堆栈指针)作为指令加载

标签: linkerstm32gnu

解决方案


我通过咨询 gnu 链接器页面设法解决了一个问题。我所做的是指定这样一个部分的运行时偏移量。

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

它的作用是:

  • .text (0x00200000 + SIZEOF(.isr_vector))使用向量表大小的偏移量指定运行时地址。我的指针现在已正确解决
  • AT>ROM_AXIM将代码放在首先产生偏移量的向量表之后。上面的行修复了它。
  • -

推荐阅读