Перейти к содержанию
    

прыгнуть на другой адрес в ROM

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

 

MCU: at91sam7s256

toolchain: Yagarto (gcc-4.2.1)

 

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

 

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

 

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

 

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

 

Спасибо!

fwdat91boot.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не специалист, увы, но по моим соображениям:

- внушает опасение длина кода (orig 0x001004f8, LENGTH = 0x00010000), а ведь остается (0x10000 - 0x4f8).

- а объектники линкуются в один файл? или создаете два образа, которые потом прошиваете один за другим?

- стоило бы скачать прошивку с цели и посмотреть, есть ли в 0x1004fd искомое, а то может, его просто нет...

Наверно, так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не специалист, увы, но по моим соображениям:

- внушает опасение длина кода (orig 0x001004f8, LENGTH = 0x00010000), а ведь остается (0x10000 - 0x4f8).

гм.. я сейчас не на работе, в понедельник проверю.

 

- а объектники линкуются в один файл? или создаете два образа, которые потом прошиваете один за другим?

Я создаю два разных образа и прошиваю один за другим.

 

- стоило бы скачать прошивку с цели и посмотреть, есть ли в 0x1004fd искомое, а то может, его просто нет...

Наверно, так.

образ прошивается правильно, по крайней мере по адресу 0x1004fd он находится, проверял с помощью SAM-BA.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

делал нечто похожее, но на lpc2378. Проблема была в том, что startup от первого приложения переводил процессор в user mode, соответственно startup от второго приложения уже не мог переключиться в supervisor mode (нужно для инициализации стеков в каждом их режимов). Все заработало после того, как я убрал перевод первого приложения в user mode из startup.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

делал нечто похожее, но на lpc2378. Проблема была в том, что startup от первого приложения переводил процессор в user mode, соответственно startup от второго приложения уже не мог переключиться в supervisor mode (нужно для инициализации стеков в каждом их режимов). Все заработало после того, как я убрал перевод первого приложения в user mode из startup.

 

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

 

Проверил весь стартап, нигде переключения в user режим не обнаружил. Даже не знаю, что еще проверить...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А Вы можете сдампить прошивку контроллера и выложить ее? Хекс, без отладочных файлов... В симулятор загнать, посмотреть, чего он там творит... По-иному не знаю, как.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А Вы можете сдампить прошивку контроллера и выложить ее? Хекс, без отладочных файлов... В симулятор загнать, посмотреть, чего он там творит... По-иному не знаю, как.

 

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

 

А что за симулятор? У меня gnu-arm тулчейн, в комлекте ничего похожего на симулятор нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

у Вас есть gdb. Но я им пользоваться не умею... Загляните в раздел gnu/open source, или ман по gdb.

Идея в том, чтобы посмотреть какие инструкции ядро выполняет перед переходом и куда оно после него уходит. Это можно с помощью симулятора сделать (эмулирует работу контроллера на персоналке) или с помощью эмулятора (jtag, например).

Хотя не факт, что хекс Вам поможет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я создаю два разных образа и прошиваю один за другим.
Возьмите каждый из этих образов (.elf) и при помощи arm-elf-objcopy получите дизассемблерный листинг каждого из них. После этого пройдите "в уме" каждый листинг по командам и убедитесь, что

1) программы располагаются в тех адресах, куда вы их хотели разместить

2) они пытаются делать то, что вы от них хотели.

 

Еще посмотрите, не затирает ли самба одну прошивку другой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

у Вас есть gdb. Но я им пользоваться не умею... Загляните в раздел gnu/open source, или ман по gdb.

Идея в том, чтобы посмотреть какие инструкции ядро выполняет перед переходом и куда оно после него уходит. Это можно с помощью симулятора сделать (эмулирует работу контроллера на персоналке) или с помощью эмулятора (jtag, например).

Хотя не факт, что хекс Вам поможет.

 

Да, я уже прочитал в хелпе про target sim. Про gdb не забыл, просто ввело в ступор слово "симуляция" :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что, собственно, располагается по адресу 0x1004f8? А Вы что ожидаете по этому адресу? main()?

Так оно не должно там быть.

А startup код у Вас есть? Где он? В обоих программах?

Startup конечно же есть.

 

И дайте вывод

arm-elf-objdump -SD app1.elf
arm-elf-objdump -SD app2.elf

Приаттачил вывод objdump, C-startup и линк-скрипты (код немного модифицировался, размер бинарника и адрес второго образа тоже).

boot.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И дайте вывод

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?

 

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

 

Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

 

Поизучал полученный дамп, но вроде никакого криминала не обнаружилось.
Нифига себе - никакого :)

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

 

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

 

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

 

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

 

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

 

Но этот код должен исполняться не с 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, определенную ранее. правильно я понимаю?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...