GNU 链接器,同一内存区域的不同寻址

GNU linker, different adressing for same memory region

所以我有一个用于我的 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 处加载指令,并通过这样做将加载向量 table(堆栈指针)的第一个条目作为指令

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

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

它的作用是:

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