Линкер GNU, разные адреса для одной и той же области памяти - PullRequest
1 голос
/ 22 февраля 2020

Итак, у меня есть простой скрипт компоновщика для моего 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 - это одно и то же хранилище fla sh. Как сказать компоновщику, что это физически то же хранилище, но доступ к нему осуществляется на отдельных шинах. Так что это ссылки, как будто это две отдельные шины, но текстовый раздел должен фактически следовать .isr_vector сразу в памяти, и смещение учитывается

Например, вот мой bin-файл, который будет go to fla sh:

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

Как вы видите, много fla sh потрачено впустую, и он попытается написать этот бин также и за пределами fla sh.

VS:

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 и, тем самым, загружать первую запись таблицы векторов (указатель стека) как инструкцию

1 Ответ

1 голос
/ 22 февраля 2020

Мне удалось решить проблему, обратившись к странице компоновщика GNU. То, что я сделал, чтобы указать смещение во время выполнения для раздела, как это.

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

Что он делает:

  • .text (0x00200000 + SIZEOF(.isr_vector)) указать адрес во время выполнения со смещением вектора размер стола. мои указатели теперь разрешены правильно
  • AT>ROM_AXIM размещает код сразу после таблицы векторов, которая вывела смещение на первое место и строка выше исправляет это.
...