реклама на сайте
подробности

 
 
> прыгнуть на другой адрес в ROM
romez777
сообщение Apr 5 2008, 08:17
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077



Приветствую,

MCU: at91sam7s256
toolchain: Yagarto (gcc-4.2.1)

Есть два простых приложения. Образ первого (размером XXX байт) расположен по адресу 0x100000 (т.е. в самом начале флеша), печатает строку в DBGU и переходит на адрес, по которому расположен другой образ.

Второй образ лежит по адресу 0x100000 + XXX . Все что он делает это выводит другую строку в DBGU и на этом успокаивается.

Но проблема в том, что переход по этому адресу не происходит! Адреса прописал верно, скрипты линкера подлправил. Не знаю, что я упустил...

Прикладываю маленкьй архив с кодом обоих приложений и ld-скриптов. Очень надеюсь, что знающие люди подскажут где я облажался.

Спасибо!
Прикрепленные файлы
Прикрепленный файл  fwdat91boot.zip ( 4.81 килобайт ) Кол-во скачиваний: 122
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
amw
сообщение Apr 7 2008, 11:24
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



Цитата(romez777 @ Apr 5 2008, 11:17) *
Приветствую,

MCU: at91sam7s256
toolchain: Yagarto (gcc-4.2.1)

Есть два простых приложения. Образ первого (размером XXX байт) расположен по адресу 0x100000 (т.е. в самом начале флеша), печатает строку в DBGU и переходит на адрес, по которому расположен другой образ.

Второй образ лежит по адресу 0x100000 + XXX . Все что он делает это выводит другую строку в DBGU и на этом успокаивается.

Но проблема в том, что переход по этому адресу не происходит! Адреса прописал верно, скрипты линкера подлправил. Не знаю, что я упустил...

Прикладываю маленкьй архив с кодом обоих приложений и ld-скриптов. Очень надеюсь, что знающие люди подскажут где я облажался.

Спасибо!

А что, собственно, располагается по адресу 0x1004f8? А Вы что ожидаете по этому адресу? main()?
Так оно не должно там быть.
А startup код у Вас есть? Где он? В обоих программах?
И дайте вывод
Код
arm-elf-objdump -SD app1.elf
arm-elf-objdump -SD app2.elf

PS: insight просимулирует этот код, но без периферии. Да из eclipse на gdb при target sim. Не знаю, входит ли insight в Yagarto. Я сам собирал.

Сообщение отредактировал amw - Apr 7 2008, 11:29


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
romez777
сообщение Apr 9 2008, 09:21
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077



Цитата(amw @ Apr 7 2008, 14:24) *
И дайте вывод
Код
arm-elf-objdump -SD app1.elf
arm-elf-objdump -SD app2.elf


Поизучал полученный дамп, но вроде никакого криминала не обнаружилось. Вот так выглядят инструкции перехода на другой образ:

Код
...
    ((funct)0x100580)();
  1002f2:    4b06          ldr    r3, [pc, #24]    (10030c <.text+0x30c>)
  1002f4:    f000 f80c     bl    100310 <.text+0x310>
...


Может быть стартап второго приложения нужно переписать (на данный момент он идентичен с первым), ведь первое приложение все уже инициализирует, во втором наверное достаточно только настроить стек и bss?

Есть еще какие-то идеи?

Спасибо!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 9 2008, 10:35
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(romez777 @ Apr 9 2008, 12:21) *
Может быть стартап второго приложения нужно переписать (на данный момент он идентичен с первым), ведь первое приложение все уже инициализирует, во втором наверное достаточно только настроить стек и bss?
А вот этого делать ни в коем случае не нужно. Мало ли что понанастраивало первое приложение. Второму виднее, что ему нужно и пусть оно настроит все, в чем нуждается. Иначе у вас будет слишком большая зависимость второго приложения от первого.


Цитата(romez777 @ Apr 9 2008, 12:21) *
Поизучал полученный дамп, но вроде никакого криминала не обнаружилось.
Нифига себе - никакого smile.gif
Код
00100000 <_startup>:
//*- If an exception occurs before remap, this would result in an infinite loop.
//*- To ensure if a exeption occurs before start application to infinite loop.
//*------------------------------------------------------------------------------*/

                B           InitReset           /* 0x00 Reset handler */
  100000:    ea000010     b    100048 <InitReset>
Но этот код должен исполняться не с 100000, а с нуля, хотя расположен должен быть действительно по адресу 100000. Kоманда B, будучи перемещенная в адрес 0, прыгнет совсем не туда, куда вы хотите, ибо использует относительную адресацию. Вы попадете на адрес 0x48, и надо ли описывать, что произойдет после ремапа? В начале этого стартапа крупными буквами написано:
Цитата
Generic CStartup for KEIL and GCC No Use REMAP
Он предназначен для линковки с адреса 0.

Второе приложение у вас находится в том же секторе, что и первое. Интересно, как ваш загрузчик будет его стирать? Вместе с собой? Надо сразу распределять память под приложение правильно.

Прикладываю свой вариант стартапа, скриптов линкера и "рыбу" загрузчика. Проверка целостности приложения происходит в __low_level_init(). Если приложение можно запускать, оно тут же и запускается (приложение получает практически всю периферию нетронутой - только запущен PLL и настроено направление портов). Если нельзя - после возврата из __low_level_init() заканчиввается инициализация загрузчика и запуск main() собственно загрузчика. Приложение использует этот же стартап-код из crt.s.
Прикрепленные файлы
Прикрепленный файл  boot_GCC.zip ( 6.49 килобайт ) Кол-во скачиваний: 95
 


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
romez777
сообщение Apr 10 2008, 05:47
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077



Здравствуйте,

большое спасибо за ценные замечания.

У меня все же путаница в голове о ремаппинге и пр. Вот мое видение - поправьте, если что-то не так.

После ресета АРМ переходит на адрес 0х0 и выполняет найденную там инструкцию; обычно по этому адресу располагается таблица векторов.

Обычно девайсы грузятся с ROM'a. Согласно даташиту, ПЗУ в SAM7 после сброса чипа (и до ремапа) доступно по адресу 0x0; также в любое время к флешу можно обратиться по адресу 0x00100000 - т.е. флэш "двуликий" smile.gif

RAM, в свою очередь, располагается по адресу 0x00200000. После ремапа - с адреса 0x0.

Как я понял, основная польза от ремапа в том, чтобы код выполнялся из SRAM, что значительно быстрее, и для модификации таблицы векторов. А также при работе с флешом (запись, чтение) - функции, оперирующие с флешем, должны выполняться из RAM.

Цитата(Сергей Борщ @ Apr 9 2008, 13:35) *
Но этот код должен исполняться не с 100000, а с нуля, хотя расположен должен быть действительно по адресу 100000.

Понятно, ведь ARM стартует с 0x0. Но тогда почему все атмеловские примеры для САМ7 привязываются к 0x100000 (это и по objdump видно, и по линк-скриптам)....

Цитата
Kоманда B, будучи перемещенная в адрес 0, прыгнет совсем не туда, куда вы хотите, ибо использует относительную адресацию. Вы попадете на адрес 0x48, и надо ли описывать, что произойдет после ремапа? В начале этого стартапа крупными буквами написано: Он предназначен для линковки с адреса 0.

Вот здесь опять конфуз в голове... Ведь после ремаппинга RAM также доступна с 0x0. Или здесь под адресами линковки подразумевается только internal flash?

Цитата
Второе приложение у вас находится в том же секторе, что и первое. Интересно, как ваш загрузчик будет его стирать? Вместе с собой? Надо сразу распределять память под приложение правильно.

Прикладываю свой вариант стартапа, скриптов линкера и "рыбу" загрузчика. Проверка целостности приложения происходит в __low_level_init(). Если приложение можно запускать, оно тут же и запускается(приложение получает практически всю периферию нетронутой - только запущен PLL и настроено направление портов). Если нельзя - после возврата из __low_level_init() заканчиввается инициализация загрузчика и запуск main() собственно загрузчика. Приложение использует этот же стартап-код из crt.s.

Я посмотрел стартап, не заметил больших отличий от того, что я использую (из атмеловского примера). Только в main.c вы делаете ремап (устанавливаете битик в MC_RCR). И есть разница в линкерном скрипте... Вот это:

Код
SECTIONS
{
  .vectors :
  {
    *(.vectors)
    KEEP(*(.vectors))
  } > REMAPED AT > ROM


говорит линкеру грузить секцию .vectors в область REMAPED, определенную ранее. правильно я понимаю?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 10 2008, 06:36
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(romez777 @ Apr 10 2008, 08:47) *
Обычно девайсы грузятся с ROM'a. Согласно даташиту, ПЗУ в SAM7 после сброса чипа (и до ремапа) доступно по адресу 0x0; также в любое время к флешу можно обратиться по адресу 0x00100000 - т.е. флэш "двуликий" smile.gif

RAM, в свою очередь, располагается по адресу 0x00200000. После ремапа - с адреса 0x0.
Как я понял, основная польза от ремапа в том, чтобы код выполнялся из SRAM, что значительно быстрее, и для модификации таблицы векторов. А также при работе с флешом (запись, чтение) - функции, оперирующие с флешем, должны выполняться из RAM.
абсолютно правильно. Кроме записи-чтения флеша. Чтение может выполняться откуда угодно, а при записи в ОЗУ должна находиться лишь мааленькая функция:
Код
void flash_t::command_RAM(uint32_t command)
{
    AT91C_BASE_MC->MC_FCR = command;
    while(!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY))
     ;
}
А вызываться она может из флеша:
Код
void flash_t::command(uint32_t command, uint32_t mode)
{
     disable_interrupts();
    AT91C_BASE_MC->MC_FMR = mode;
    command_RAM(command);
    enable_interrupts();
}

void flash_t::program(uint32_t const *page_addr)
{
    command( ((AT91C_MC_KEY / 0xFFU) * 0x5A) | (((uint32_t)page_addr >> 7) << 8) | AT91C_MC_FCMD_START_PROG,
                (0 * AT91C_MC_FRDY) | (0 * AT91C_MC_LOCKE) | ( 0 * AT91C_MC_PROGE) |
                (1 * AT91C_MC_NEBP) | (FLASH_WAITSTATES) | (AT91C_MC_FMCN / 0xFFU * MCK_CYCLES)
           );
}
Цитата(romez777 @ Apr 10 2008, 08:47) *
Понятно, ведь ARM стартует с 0x0. Но тогда почему все атмеловские примеры для САМ7 привязываются к 0x100000 (это и по objdump видно, и по линк-скриптам)....
Видимо у них первой командой идет не B, а LDR PC,[PC, #24], которая грузит в PC абсолютный адрес, расположенный тут же в сегменте векторов. Т.е. для первой команды все равно где располагаться, а вторая передаст управление на абсолютный адрес во флеше, т.е дальше программа работает в адресах 0x10.... Почему они линкуют вектора на абсолютные адреса флешь - загадка. Может быть, для упрощения скрипта. А может просто исходят из того, что поскольку и в адресах флеша и в нулевых адресах лежат копии, то как бы все равно, откуда реально исполняется код. Ну побегает он по нулевым, потом на первой же команде абсолютного перехода перескочит в адреса флеш. Но если, находясь в нулевых адресах, он сделает ремап - наступит карамба, поскольку следующую команду он неожиданно получит из ОЗУ.
Цитата(romez777 @ Apr 10 2008, 08:47) *
Вот здесь опять конфуз в голове... Ведь после ремаппинга RAM также доступна с 0x0.
Да. А в начало RAM перед ремапом скопирован сегмент векторов приложения. Код в это время исполняется уже с адресов 0x10...., и передав выполнение на адрес 0 мы попадаем на начальную команду приложения. А там стоит LDR PC, [PC, #24], а по адресу 0x20 лежит абсолютный адрес начала стартапа приложения. Он грузится в PC и управление снова попадает на адреса флеш, куда-то после 0x101000. При этом приложение имеет свой сегмент векторов, который совершенно независим от векторов загрузчика. Ближе к обеду еще раз внимательно изучу ваш код, возможно вы пытались построить передачу управления на другом принципе.
Цитата(romez777 @ Apr 10 2008, 08:47) *
Вот это:
говорит линкеру грузить секцию .vectors в область REMAPED, определенную ранее. правильно я понимаю?
Не совсем. Оно говорит, что во время исполнения эта секция будет находиться в области REMAPED. Поэтому все ссылки из нее должны быть установлены так, как будто она находится в области REMAPED. Но физически эти байты надо сложить в область ROM. Аналогично для секции .data - все ссылки будут на область RAM, а физически начальные значения будут сложены в область ROM. Как будет происходить перемещение кода (ремап или копирование, как для секции .data), линкер не знает.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
romez777
сообщение Apr 10 2008, 14:46
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077



Приветствую.

Все немного проясняется, из мозаики складывается картинка smile.gif Но все же не до конца представляю: для моей задачи (бутлоадер), нужен ли стартап с remap или без оного? Отсюда соответственно и линкер срипт.

И еще. Как Вы уже упомянули, мой первоначальный startup-код "должен исполняться не с 100000, а с нуля, хотя расположен должен быть действительно по адресу 100000". Почему тогда в отдельности (т.е. _без_ перехода на второй образ) этот простой код работает?

И вот еще по адресам: как я понимаю, до ремапа все адреса, о которых мы говорили, физические (например, физически флеш находится по адресу 0x100000, но отмаплена на 0х00 при старте), а после ремапа - они логические?

Цитата
Не совсем. Оно говорит, что во время исполнения эта секция будет находиться в области REMAPED. Поэтому все ссылки из нее должны быть установлены так, как будто она находится в области REMAPED. Но физически эти байты надо сложить в область ROM. Аналогично для секции .data - все ссылки будут на область RAM, а физически начальные значения будут сложены в область ROM. Как будет происходить перемещение кода (ремап или копирование, как для секции .data), линкер не знает.

Ваш стартап использует remap; вопрос - область REMAPED, описанная в линкер скрипте, определяет именно SRAM область после ремапа - правильно я понимаю?

Спасибо !
Go to the top of the page
 
+Quote Post
amw
сообщение Apr 11 2008, 07:56
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



Цитата(romez777 @ Apr 10 2008, 17:46) *
Все немного проясняется, из мозаики складывается картинка smile.gif Но все же не до конца представляю: для моей задачи (бутлоадер), нужен ли стартап с remap или без оного? Отсюда соответственно и линкер срипт.

Зависит от того, как Вы напишете бутлоадер.
Например часть кода из стартап линкуется для исполнения во флеш. А все остальное слинковано для выполнения в ОЗУ. Если нужны прерывания - то ремап думаю нужен (если обработчики в ОЗУ то лучше и вектора туда положить).
Цитата
И еще. Как Вы уже упомянули, мой первоначальный startup-код "должен исполняться не с 100000, а с нуля, хотя расположен должен быть действительно по адресу 100000". Почему тогда в отдельности (т.е. _без_ перехода на второй образ) этот простой код работает?

Первые команды (бутлоадер) пользуясь относительной адрессацией выполняют переход по абсолютному адресу.
Во второй части программы (собственно программа) то-же самое, но смещения не верны из-за того, что код расположен не с нулевого адреса.
И ОЗУ и флеш доступны одноврнменно и по адресу 0 и по их фактическому = абсолютному адресу и смщения как от нуля так и от, скажем 100000 для флеш одинаковы как от 0 так и от 100000 для бутлоадера, а вот для основной программы - нет.
Цитата
И вот еще по адресам: как я понимаю, до ремапа все адреса, о которых мы говорили, физические (например, физически флеш находится по адресу 0x100000, но отмаплена на 0х00 при старте), а после ремапа - они логические?

Нет. В этом процессоре все адреса физические. Просто флеш (или ОЗУ) доступна одновременно по двум адресам.


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
romez777
сообщение Apr 12 2008, 04:11
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077



Здравствуйте,

Цитата(amw @ Apr 11 2008, 10:56) *
Зависит от того, как Вы напишете бутлоадер.
Например часть кода из стартап линкуется для исполнения во флеш. А все остальное слинковано для выполнения в ОЗУ. Если нужны прерывания - то ремап думаю нужен (если обработчики в ОЗУ то лучше и вектора туда положить).

Я делаю бутлоадер для конкретного применения, т.е. он не универсальный, а будет обновлять в железке конкретное ПО, которое активно использует прерывания (fiq и irq), работает с TWI, spi и пр.
То есть remap таки нужен?

Цитата
Нет. В этом процессоре все адреса физические. Просто флеш (или ОЗУ) доступна одновременно по двум адресам.

Еще такой фундаментальный вопрос... Чего я до конца не понимаю - код ведь всегда будет выполняться из RAM, или это определяется линковкой? То есть ежели линкуем с FLASH адресами (и нет ремаппинга), то код будет выполняться из флеш. В потивном случае - если слинковали с SRAM и включен ремаппинг, код будет выполняться из RAM.

Правильно ли я понимаю? Это справедливо для всех ARM-ов или только sam7?

Спасибо.
Go to the top of the page
 
+Quote Post
amw
сообщение Apr 12 2008, 07:30
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



Цитата(romez777 @ Apr 12 2008, 07:11) *
Здравствуйте,
Я делаю бутлоадер для конкретного применения, т.е. он не универсальный, а будет обновлять в железке конкретное ПО, которое активно использует прерывания (fiq и irq), работает с TWI, spi и пр.
То есть remap таки нужен?

Если Вам в основной программе нужны вектора, то располагайте вектора в ОЗУ (линкуйте вектора для ОЗУ), копируйте вектора в ОЗУ и делайте потом REMAP.
Цитата
Еще такой фундаментальный вопрос... Чего я до конца не понимаю - код ведь всегда будет выполняться из RAM, или это определяется линковкой? То есть ежели линкуем с FLASH адресами (и нет ремаппинга), то код будет выполняться из флеш. В потивном случае - если слинковали с SRAM и включен ремаппинг, код будет выполняться из RAM.

Правильно ли я понимаю? Это справедливо для всех ARM-ов или только sam7?

Ой ни ни!!!!
Не правильно!
Линковка определяет абсолютные адреса по кторым будут располягаться функции и данные фактически.
В процессоре имеется:
1. Вектора, и они всегда по нулевому адресу.
2. Флеш, она хранит и программу и данные. Находится по адресу X. Данные в ней не модифицируются и при отключении питания не теряются.
3. ОЗУ, она хранит и программу и данные. Гаходится по адресу Y. Данные в нет теряются при выключении питания. Но быстрее флеш.

Если Вам нужно иметь быстрый код - линкуйте его в ОЗУ. Но! При выключении питания этот код исчезает. Так как он попадет в ОЗУ при следующем включении?
А очень просто! Он хранится во флеш и при каждом включении питания программа, запускаемая из флеш копирует нужный кусок в ОЗУ.
Как это обеспечить? При линковке, все команды перехода используют абсолютный адрес ОЗУ для вычисления адреса конкретной команды перехода. Линкер складывает в HEX файл все подряд. Сначала то, что слинковано для запуска из флеш по адресам во флеш, где этот код должен находится во время выполнения программы.
За ним (за этим кодом) фо флеш лежит копия того, что должно во время выполнения быть в ОЗУ. А стартап код выполняет копирование этой копии в ОЗУ по нужным адресам.

Вектора находятся по адресу ноль. И как не линкуй, а вектора должны быть по адресу ноль и только ноль. Так что же делать? Да просто сделать так, что бы флеш или ОЗУ было видно по адресу ноль. Как это сделать? Ну в процесоре ставят "хитрый" адресный дешифратор, который в зависимости от бита REMAP будет показывать по нулевому адресу либо флеш либо ОЗУ. Тут главное обеспечить из вектора команду перехода так, что бы он "послал" процессор по правильному абсолютному адресу!

Не зависимо от REMAP и флеш и ОЗУ остаются доступны по своим адесам. То есть по адресу X всегда видна флеш а адресу Y всегда видно ОЗУ. А адресу ноль видно "то же самое" что и во флеш/ОЗУ. Что именно видно по адресу ноль - зависит текущего значения REMAP.
Но прогамма слинкованная для ОЗУ, расположенному по адресу Y не может выполнятся по адресам, видимым начиная с нуля! Тогда в вектора ставятся адреса перехода, указывающие адреса ОЗУ.

В разных АРМ по разному. В SAM7 все ОЗУ или вся флеш мапится на нолевой адрес, в LPC - только первые 64 байта (то есть сами вектора и место для указания абсолютных адресов перехода).

bb-offtopic.gif
Представте, что Вы сидите в комнате. Слева у Вас окно, и Вы в нем видите море. Справа у Вас окно, и Вы в нем видите горы. А прямо перед Вами супер пупер фул ХД телевизор. К телевизору подключены две камеры. Однв показывает то, что видно в левом окне, а вторая - то что в правом.
Море - это флеш. Горы - это ОЗУ. Телевизор - это то что видно по адресу ноль.
Щелкая ДУ телевизора Вы можете видеть либо море, либо горы. То есть либо флеш, либо ОЗУ переключая бит REMAP.
НО!!! В телевизоре Вы можете только видеть. Телевизор не становится ни морем ни горами.
Так вот Вы - процессор АРМ smile.gif . Вы можете посмотреть в телевизор и узнать, в какое окно Вам прыгать smile.gif то есть по какому адресу должен быть переход.

Сообщение отредактировал amw - Apr 12 2008, 07:46


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
romez777
сообщение Apr 14 2008, 07:28
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077



Большое спасибо за подробные разъяснения!

Цитата(amw @ Apr 12 2008, 10:30) *
Если Вам в основной программе нужны вектора, то располагайте вектора в ОЗУ (линкуйте вектора для ОЗУ), копируйте вектора в ОЗУ и делайте потом REMAP.


Таким образом, в _основной_ программе мне нужны вектора (обработчики fiq и irq):
1) в основной программе (загружаемой бутлоадером) копируем таблицу векторов в RAM, далее устанавливаем бит remap, тем самым отмапливаем ОЗУ по адресам 0x200000 И 0x0
2) бутлоадер - ремап не обязателен, ведь нам нужно только загрузить приложение куда следует, а оно уже само разберется. Как я понял, ремаппинг может понадобиться только для работы с флэшем, чтобы избежать compiler-specific фич (например, __ramfunc в IAR'e).

Такая концепция верная?

Цитата
...
Ну в процесоре ставят "хитрый" адресный дешифратор, который в зависимости от бита REMAP будет показывать по нулевому адресу либо флеш либо ОЗУ. Тут главное обеспечить из вектора команду перехода так, что бы он "послал" процессор по правильному абсолютному адресу!

Здесь речь идет о командах типа B, BL, BX или что-то другое? Есть какие-то специализированные инструкции послать процессор по абсолютному адресу?
Go to the top of the page
 
+Quote Post
amw
сообщение Apr 14 2008, 13:22
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



Цитата(romez777 @ Apr 14 2008, 10:28) *
Большое спасибо за подробные разъяснения!
Таким образом, в _основной_ программе мне нужны вектора (обработчики fiq и irq):
1) в основной программе (загружаемой бутлоадером) копируем таблицу векторов в RAM, далее устанавливаем бит remap, тем самым отмапливаем ОЗУ по адресам 0x200000 И 0x0
2) бутлоадер - ремап не обязателен, ведь нам нужно только загрузить приложение куда следует, а оно уже само разберется. Как я понял, ремаппинг может понадобиться только для работы с флэшем, чтобы избежать compiler-specific фич (например, __ramfunc в IAR'e).

Примерно так.
Учтите, что в ОЗУ копировать нужно вектора ПРИЛОЖЕНИЯ ане бутлоадера. При этом векора приложения сами должны быть слинкованы по адресу ноль, а остальное приложение по его родному адресу.
Цитата
Такая концепция верная?
Здесь речь идет о командах типа B, BL, BX или что-то другое? Есть какие-то специализированные инструкции послать процессор по абсолютному адресу?

Команды B и BL используют относительную адресацию.
В них указывается смещение (т.е. разница) до нужного адреса от текущего значения PC. Это смещение должно после копирования векторов в ОЗУ соответствовать расположению программы (обработчика).
Команда BX использует абсолютную адресацию.
То есть для команды BX абсолютный адрес перехода находится в регистре. Как он туда попал - вот это вопрос.

А вот дальше не уверен что все правильно распишу, поправте кто-нибудь, если я лажанулся.
Команда LDR PC, AAA использует значение AAA как смещение от текущего PC до адреса, где лежит абсолютный адрес перехода. Брррр.
Пример
Код
EXCEPTION_VECTORS:
    ldr    pc, RESET_ADDR
    ldr    pc, UNDEF_ADDR
    ldr    pc, SWI_ADDR
    ldr    pc, PREFETCH_ABORT_ADDR
    ldr    pc, DATA_ABORT_ADDR
    .word    0
    ldr    pc, IRQ_ADDR
    ldr    pc, FIQ_ADDR
RESET_ADDR:        .word    _start
UNDEF_ADDR:        .word    UNDEF_handler
SWI_ADDR:        .word    SWI_handler
PREFETCH_ABORT_ADDR:    .word    PREFETCH_ABORT_handler
DATA_ABORT_ADDR:    .word    DATA_ABORT_handler
IRQ_ADDR:        .word    IRQ_handler
FIQ_ADDR:        .word    FIQ_handler
UNDEF_handler:
    Код исключения
SWI_handler:
    Код исключения
PREFETCH_ABORT_handler:
    Код исключения
DATA_ABORT_handler:
    Код исключения
IRQ_handler:
    Код исключения
FIQ_handler:
    Код исключения
    ..................
_start:
    ..................

В данном примере команда
ldr pc, IRQ_ADDR
Загрузит в PC число, лежащее в памяти по адресу IRQ_ADDR.
По адресу IRQ_ADDR лежит число = адресу собственно обработчика прерывания IRQ_handler.


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
romez777
сообщение Apr 15 2008, 13:31
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077



Цитата(amw @ Apr 14 2008, 16:22) *
Примерно так.
Учтите, что в ОЗУ копировать нужно вектора ПРИЛОЖЕНИЯ ане бутлоадера. При этом векора приложения сами должны быть слинкованы по адресу ноль, а остальное приложение по его родному адресу.


Приветствую.
Есть вопрос по линкер-скрипту приложения. Взял скрипт из одного из атмеловсеих примеров под gcc и немного переделал. Вот что получилось:

Код
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_startup)

/* Memory layout */
MEMORY
{
  ROM (rx) : ORIGIN = 0x00101000, LENGTH = 0x00001000    /* 4K is enough for bootloader */
  RAM (rw) : ORIGIN = 0x00200000, LENGTH = 0x00004000    /* any SAM7 has at least 16K RAM */
  STACK (rw) : ORIGIN = 0x00204000,LENGTH = 0x00000000
  REMAPPED (rwx) : ORIGIN = 0x00000000, LENGTH = LENGTH(RAM)
}

/* Section Definitions */
SECTIONS
{
  /* place vectors at 0x0 */
  .vectors :
  {
    _vectors_start = .;
    *(.vectors)
    KEEP(*(.vectors))
    _vectors_end = .;
  } >REMAPPED AT >ROM

  /* first section is .text which is used for code */
  /*. = 0x0000000;*/
  .text : { *Cstartup.o (.text) } >ROM =0
  .text :
  {
    *(.text)        /* code */
    *(.rodata)        /* read-only data (constants) */
    *(.rodata*)

    *(.glue_7t) *(.glue_7)

  } >ROM =0

  . = ALIGN(4);

  _etext = .;
  PROVIDE (etext = .);

  /* .data section which is used for initialized data */
  .data :
  {
    _data = .;
    *(.ramfunc)        /* copy ramfunc code to RAM in same cycle with data init values */
    *(.data*)
  } >RAM AT >ROM     /* place init values immediatly after .text section */
  . = ALIGN(4);

  _edata = .;
   PROVIDE (edata = .);

  /* .bss section which is used for uninitialized data */
  .bss :
  {
    __bss_start = .;
    __bss_start__ = .;
    *(.bss)
    *(COMMON)
  } >RAM
  . = ALIGN(4);
  __bss_end__ = .;
  __bss_end__ = .;
  _end = .;
  /*PROVIDE (end = .);*/

   .int_data :  
   {
   *(.internal_ram_top)
   }> STACK

  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }

}


После компиляции смотрю map-файл (он генерируется гнушным линкером и содержит карту памяти) и вижу, что секция vectors занимает 0 байт sad.gif Что неправильно в этом скрипте?

Спасибо.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 15 2008, 13:50
Сообщение #14


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(romez777 @ Apr 15 2008, 16:31) *
После компиляции смотрю map-файл (он генерируется гнушным линкером и содержит карту памяти) и вижу, что секция vectors занимает 0 байт sad.gif Что неправильно в этом скрипте?
А в файле с исходным текстом указано, что вектора надо класть в секцию vectors? Сделайте дизассемблерный файл и посмотрите, куда они попали на самом деле.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
romez777
сообщение Apr 16 2008, 00:19
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077



Здравствуйте.

Цитата(Сергей Борщ @ Apr 15 2008, 16:50) *
А в файле с исходным текстом указано, что вектора надо класть в секцию vectors?


В оригинальном стартапе вектора не были оформлены в отдельную секцию директивой .section, поэтому я сделал таким образом:

Код
...
       .section .vectors
       .global _startup
        .func _startup

_startup:
reset:
                B           InitReset           /* 0x00 Reset handler */
undefvec:
                B           undefvec            /* 0x04 Undefined Instruction */
swivec:
                B           swivec              /* 0x08 Software Interrupt */
pabtvec:
                B           pabtvec             /* 0x0C Prefetch Abort */
dabtvec:
                B           dabtvec             /* 0x10 Data Abort */
rsvdvec:
                B           rsvdvec             /* 0x14 reserved  */
irqvec:
                B           IRQ_Handler_Entry   /* 0x18 IRQ     */
fiqvec:
        B           fiqvec        /* 0x1c FIQ    */

FIQ_Handler_Entry:
/* здесь обработчик FIQ */

InitReset:
       .extern   AT91F_LowLevelInit
/*- minumum C initialization */
/*- call  AT91F_LowLevelInit( void) */
...


Как я догадываюсь (в документации на GNU assembler не нашел явной информации), сеция определенная с помощью .section простирается до следующей директивы .section. Но вот откуда начинается следующая за .vectors секция, т.е. .text? smile.gif С вектора InitReset?

А вот так копируются вектора в память с последующим ремапом:
Код
/* Copy exception vectors in RAM */
        LDR     r0, =_vectors_start
        LDR     r1, =0x00200000
        LDR     r2, =_vectors_start
copy:
        LDR     r3, [r0], #4
        STR     r3, [r1], #4
        CMP     r0, r2
        BNE     copy

/* Remap SRAM to have new exception vectors at address 0 */
        LDR     r0, =0xFFFFFF00
        LDR     r1, =(0x1 <<  0)
        STR     r1, [r0, #0]

        ldr    lr,=exit
        ldr    r0,=main
        bx    r0


Цитата
Сделайте дизассемблерный файл и посмотрите, куда они попали на самом деле.


Код
main.elf:     file format elf32-littlearm

Disassembly of section .text:

00101000 <_startup>:
//*- If an exception occurs before remap, this would result in an infinite loop.
//*- To ensure if a exeption occurs before start application to infinite loop.
//*------------------------------------------------------------------------------*/

                B           InitReset           /* 0x00 Reset handler */
  101000:    ea000011     b    4c <InitReset>

00101004 <undefvec>:
...

Должно же быть "b 0x0 ..."? Гм...
Go to the top of the page
 
+Quote Post
romez777
сообщение Apr 17 2008, 07:51
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077



Немного покрутил, но все равно не работает smile.gif Сейчас карта памяти вроде выглядит правильно:

Код
Memory Configuration

Name             Origin             Length             Attributes
ROM              0x00101000         0x00001000         xr
RAM              0x00200000         0x00004000         rw
STACK            0x00204000         0x00000000         rw
REMAPPED         0x00000000         0x00004000         xrw
*default*        0x00000000         0xffffffff
...
.vectors        0x00000000       0x20 load address 0x00101000
                0x00000000                _vectors_start = .
*(.vectors)
.vectors       0x00000000       0x20 Cstartup.o
                0x00000000                _startup
*(.vectors)
                0x00000020                _vectors_end = .

.text           0x00101020      0x488
*(.text)
...


То есть вектора расположились правильно и размер у них правильный - 32байта. А вот objdump:
Код
main.elf:     file format elf32-littlearm

Disassembly of section .vectors:

00000000 <_startup>:
//*- If an exception occurs before remap, this would result in an infinite loop.
//*- To ensure if a exeption occurs before start application to infinite loop.
//*------------------------------------------------------------------------------*/

                B           InitReset           /* 0x00 Reset handler */
   0:    ea040411     b    10104c <InitReset>
...

Может быть это особенность компилятора (или скорее ассемблера)?
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- romez777   прыгнуть на другой адрес в ROM   Apr 5 2008, 08:17
- - Leen   Не специалист, увы, но по моим соображениям: - вну...   Apr 6 2008, 07:54
|- - romez777   Цитата(Leen @ Apr 6 2008, 10:54) Не специ...   Apr 6 2008, 08:27
|- - Сергей Борщ   Цитата(romez777 @ Apr 6 2008, 11:27) Я со...   Apr 7 2008, 09:54
- - r301   делал нечто похожее, но на lpc2378. Проблема была ...   Apr 6 2008, 10:53
|- - romez777   Цитата(r301 @ Apr 6 2008, 13:53) делал не...   Apr 6 2008, 23:39
- - Leen   А Вы можете сдампить прошивку контроллера и выложи...   Apr 7 2008, 05:21
|- - romez777   Цитата(Leen @ Apr 7 2008, 08:21) А Вы мож...   Apr 7 2008, 06:25
- - Leen   у Вас есть gdb. Но я им пользоваться не умею... За...   Apr 7 2008, 09:29
|- - romez777   Цитата(Leen @ Apr 7 2008, 12:29) у Вас ес...   Apr 7 2008, 12:49
|- - romez777   Цитата(amw @ Apr 7 2008, 14:24) А что, со...   Apr 8 2008, 03:34
|- - romez777   Цитата(Сергей Борщ @ Apr 9 2008, 13:35) П...   Apr 12 2008, 01:28
- - amw   Да есть такая проблема. Сделайте так КодТут убрать...   Apr 17 2008, 08:07
- - romez777   Приветствую. Цитата(amw @ Apr 17 2008, 11...   Apr 18 2008, 02:17
- - amw   Цитата(romez777 @ Apr 18 2008, 05:17) При...   Apr 18 2008, 08:28
- - romez777   Приветствую. Спасибо за ваше терпение в ответах н...   Apr 19 2008, 04:02
- - amw   Цитата(romez777 @ Apr 19 2008, 07:02) При...   Apr 19 2008, 10:05
- - romez777   Цитата(amw @ Apr 19 2008, 13:05) Мой тулч...   Apr 21 2008, 02:08
- - amw   Цитата(romez777 @ Apr 21 2008, 05:08) Отл...   Apr 21 2008, 08:07
- - romez777   ЦитатаПотому что команда B использует относительну...   Apr 22 2008, 06:06
- - amw   Цитата(romez777 @ Apr 22 2008, 09:06) Фа...   Apr 22 2008, 08:49
- - romez777   ЦитатаКод/* Copy exception vectors in RAM */ LDR...   Apr 23 2008, 00:27
- - amw   Цитата(romez777 @ Apr 23 2008, 03:27) При...   Apr 23 2008, 08:16
- - romez777   ЦитатаНу Вы хоть исправили значение для конца цикл...   Apr 25 2008, 05:38
|- - amw   Цитата(romez777 @ Apr 25 2008, 08:38) В с...   Apr 25 2008, 10:07
|- - romez777   ЦитатаДа, правильно понимаете. Приложение должно и...   Apr 26 2008, 01:30
|- - amw   Цитата(romez777 @ Apr 26 2008, 04:30) Но ...   Apr 28 2008, 11:33
|- - romez777   Цитата(amw @ Apr 28 2008, 14:33) Лучше вс...   May 6 2008, 14:58
|- - amw   Цитата(romez777 @ May 6 2008, 17:58) Прив...   May 6 2008, 18:01
|- - romez777   Приветствую. Выкладываю полный архив со всеми инк...   May 7 2008, 14:49
|- - amw   Цитата(romez777 @ May 7 2008, 17:49) Прив...   May 7 2008, 15:10
|- - romez777   ЦитатаВ дизассемблере даны КОДЫ КОМАНД. В бинарике...   May 8 2008, 06:10
|- - amw   Цитата(romez777 @ May 8 2008, 09:10) Да, ...   May 8 2008, 09:12
|- - romez777   ЦитатаВсе проверил - видимо, дело в ключах компиля...   May 8 2008, 11:08
|- - amw   Цитата(romez777 @ May 8 2008, 14:08) А во...   May 8 2008, 11:20
|- - romez777   Цитата(amw @ May 8 2008, 14:20) Ну так у ...   May 9 2008, 05:37
|- - amw   Цитата(romez777 @ May 9 2008, 08:37) Я та...   May 11 2008, 10:35
|- - romez777   Цитата(amw @ May 11 2008, 13:35) 1. У Вас...   May 13 2008, 05:28
|- - amw   Цитата(romez777 @ May 13 2008, 08:28) Вот...   May 13 2008, 07:16
|- - aaarrr   Цитата(romez777 @ May 13 2008, 09:28) В с...   May 13 2008, 09:12
- - Сергей Борщ   Цитата(amw @ Apr 23 2008, 11:16) Чтобы от...   Apr 25 2008, 09:28


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 17:48
Рейтинг@Mail.ru


Страница сгенерированна за 0.01746 секунд с 7
ELECTRONIX ©2004-2016