2016-12-24 6 views
4

Я только начал с развитием вложенным руки, и есть фрагмент кода, который действительно давало мне покоя:Понимание ARM Cortex-M0 + перемещение

/* Initialize the relocate segment */ 
pSrc = &_etext; 
pDest = &_srelocate; 

if (pSrc != pDest) 
{ 
    while (pDest < &_erelocate) 
    { 
     *pDest++ = *pSrc++; 
    } 
} 

Где _etext и _srelocate символы, определенные в сценарии компоновщика:

. = ALIGN(4); 
_etext = .; 

.relocate : AT (_etext) 
{ 
    . = ALIGN(4); 
    _srelocate = .; 
    *(.ramfunc .ramfunc.*); 
    *(.data .data.*); 
    . = ALIGN(4); 
    _erelocate = .; 
} > ram 

Где ram представляет собой сегмент памяти, происхождение которых 0x20000000. Проблема, как я вижу, в том, что _etext является символом, который отмечает конечную границу сегмента .text, который является частью другого сегмента памяти, rom. Это означает, что, если вышеупомянутый сегмент памяти не был заполнен на 100%, _etext != _srelocate всегда будет правдой. Это означает, что мы копируем память за пределами раздела .text, где ничто не определено для жизни согласно сценарию компоновщика.

Для меня, это приводит к одному из трех сценариев, либо А) Существует мусор присутствует в rom вне секции .text, и она будет скопирована в .relocate (и впоследствии .data), или B) Память за .text пуста после операции стирания чипа до программирования устройства, и в этом случае .relocate обнуляется, или C) Существует некоторая небольшая магия руки, происходящая здесь, где значения .data размещаются после .text в rom и должны быть загружены в ram; в этом случае комментарий должен быть s/relocate/data.

Третий сценарий кажется наиболее вероятным, но согласно сценарию компоновщика это не может быть правдой. Может кто-то пролить свет на это?

+0

Вы правы, это третий вариант. AT() сообщает компоновщику помещать разделы .ramfunc и .data (оба из которых читаются/записываются) в объектном файле, начиная с _etext. «> Ram» сообщает компоновщику разрешить перемещение, как если бы разделы были помещены в ОЗУ. В результате цикл копирования перемещает данные из области только для чтения в область чтения/записи при запуске программы. –

+0

@RichardPennington Awesome, как вы думаете, вы могли бы добавить это в форме ответа, возможно, с цитатой из руководства ld, которое охватывает директиву AT()? –

ответ

1

Вы правы, это третий вариант. AT() говорит компоновщик поставить секции .ramfunc и .data (оба из которых чтение/запись) в файле объекта, начиная с _etext. «> Ram» сообщает компоновщику разрешить перемещение, как если бы разделы были помещены в ОЗУ, это делается с помощью команды MEMORY, описанной здесь: https://sourceware.org/binutils/docs/ld/MEMORY.html#MEMORY В результате цикл копирования перемещает данные из области только для чтения в чтение/когда программа запускается.

Вот ссылка на Л.Д. документации Гну, где контролирующей LMA (адрес нагрузки) описывается: https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html