U-Boot Как запустить автономную бинарную программу?

Я скомпилировал простой бинарный файл (hello.bin) и сохранил его на карту памяти.

Я использую комплект разработчика NXP Sabre с четырехъядерным процессором i.mx 6. Я запустил U-boot и пытаюсь получить доступ к двоичному файлу и запустить его.

Hello.bin доступен, потому что работает следующая команда:

=> fatload mmc 1:4 0x20005000 hello.bin
reading hello.bin

Я так понимаю файл должен загружаться в оперативную память по адресу 0x20005000

Итак, я хочу проверить, есть ли двоичный файл

=> md 0x20005000
20005000: 464c457f 00010101 00000000 00000000    .ELF............
20005010: 00280002 00000001 00010315 00000034    ..(.........4...
20005020: 000028f4 05000400 00200034 00280009    .(......4. ...(.
20005030: 00240025 70000001 00000454 00010454    %.$....pT...T...

Выглядит нормально, так как начальные биты совпадают с файлом, который я скопировал на SD-карту.

Когда я пытаюсь запустить двоичный файл, устройство сообщает о неопределенной инструкции:

=> go 0x20005000
## Starting application at 0x20005000 ...
undefined instruction
pc : [<20005158>]          lr : [<4ff71403>]
reloc pc : [<e7897158>]    lr : [<17803403>]
sp : 4f56dd50  ip : 00000000     fp : 00000002
r10: 4f56f938  r9 : 4f56deb0     r8 : 4ffc3c40
r7 : 4ff713d9  r6 : 00000002     r5 : 20005000  r4 : 4f56f93c
r3 : 20005000  r2 : 4f56f93c     r1 : 4f56f93c  r0 : 00000000
Flags: nzCv  IRQs off  FIQs off  Mode SVC_32
Resetting CPU ...

Спасибо за вашу помощь


person Mattis Asp    schedule 13.04.2018    source источник
comment
команда =› bdinfo, сообщила мне что-то о банке DRAM, начинается с 0x10000000 (7 нулей) и заканчивается на 0x4000000. Затем я использовал вместо него fatload mmc 1:4 0x10005000 hello.bin, который, похоже, работает. Наверное, я писал на неверный адрес. go 0x10005000 все равно не работает.   -  person Mattis Asp    schedule 13.04.2018


Ответы (3)


Пожалуйста, найдите пример в https://www.denx.de/wiki/view/DULG/UBootStandalone#Section_5.12.1.

go ожидает не начало двоичного файла ELF, а адрес процедуры ввода. Если вы хотите получить доступ к подпрограммам U-Boot, двоичный файл должен быть перемещен.

person Xypron    schedule 13.04.2018

Я скомпилировал простой бинарный файл (hello.bin) и сохранил его на карту памяти.

Вы упустили много существенных деталей.
Как вы скомпилировали эту программу, например. какой набор инструментов, какой make-файл?
Вы связали эту программу с библиотекой?

Я так понимаю файл должен загружаться в оперативную память по адресу 0x20005000

Как вы пришли к этому "пониманию"?

Обычно адрес загрузки отдельной программы зависит от нескольких факторов.
Во-первых, необходимо учитывать адреса доступной памяти (на целевой плате).
Во-вторых, если отдельная программа не может быть перемещена (что маловероятно в вашей случае), то программа должна быть загружена по ее адресу загрузки/начальному адресу, определенному при компоновке программы.
Адреса загрузки и запуска программы можно получить из ее файла карты (т. е. вывода компоновщика).

Когда я пытаюсь запустить двоичный файл, устройство сообщает о неопределенной инструкции:

Вот что происходит, когда ELF-заголовок "выполняется".
Поскольку файл явно содержит ELF-заголовок, расширение имени файла должно быть .elf, а не .bin. .
Как этот исполняемый файл получил вводящее в заблуждение имя?

Вероятно, вы не создали отдельный двоичный файл образа.
В каталоге examples/standalone/ исходного кода U-Boot есть пример кода и make-файл для создания отдельных двоичных файлов, например. a hello_world.bin.
Обязательно правильно определите CONFIG_STANDALONE_LOAD_ADDR для вашей доски!
Адрес загрузки по умолчанию обязательно должен быть неприличный.


команда => bdinfo рассказала мне что-то о банке DRAM, начиная с 0x10000000 (7 нулей) и заканчивая 0x4000000.

(Прежде всего, не помещайте существенную информацию в комментарии. Добавьте ее в свой исходный пост, используя возможность редактирования.)
Предоставленная вами «информация» не имеет смысла (т. е. конечный адрес меньше начального адреса) . Избегайте интерпретации информации, а вместо этого просто представьте (скопируйте и вставьте) фактический результат.

Затем я использовал вместо него fatload mmc 1:4 0x10005000 hello.bin, который, похоже, работает. Наверное, я писал на неверный адрес.

Команда fatload просто копирует содержимое файла в память. Истинный успех этой копии подтверждается проверкой памяти, а не завершением команды.
Ваш комментарий сбивает с толку, поскольку вы не упомянули о каких-либо предыдущих проблемах с загрузкой.

go 0x10005000 все равно не работает.

Использование произвольных адресов загрузки/запуска не является эффективным методом отладки.
Суммирование слов "похоже, работает" или "все еще не работает" является некачественным описание результатов.
См. Как правильно задавать вопросы.

person sawdust    schedule 14.04.2018
comment
Я использовал arm-fslc-linux-gnueabi-gcc для его компиляции. На самом деле я написал ${CC} myapp/helloworld.c -o hello.bin . Я хотел бы напечатать строку в helloworld на экране, UART был бы в порядке. Точный адрес, возможно, не имеет значения, но я ожидал, что мне нужно загрузить двоичный файл в память. У меня нет make-файла, и я не очень разбираюсь в компоновке. Может быть, вы могли бы указать мне в правильном направлении? - person Mattis Asp; 17.04.2018
comment
CC = arm-fslc-linux-gnueabi-gcc -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard --sysroot=/opt/fslc-framebuffer/2.4.2/sysroots/armv7at2hf-neon- fslc-linux-gnueabi - person Mattis Asp; 17.04.2018

Получил некоторую помощь от другого друга, я нашел его очень полезным, поэтому я опубликую его:

Вы можете использовать цепочку инструментов Yocto, но вы не можете связываться с библиотекой C (что делается по умолчанию), поэтому вам нужно указать некоторые дополнительные параметры для GCC, чтобы сообщить, что вы также не можете использовать инструкцию go из U-Boot для перейти к двоичному файлу ELF, который вы только что загрузили в память, двоичный файл ELF должен быть преобразован в «сырой» двоичный файл (список инструкций ARM в вашем случае) с помощью инструмента objdump. Двоичный файл ELF — это особый формат, который инкапсулирует ваш код/ваши данные и некоторую дополнительную информацию, а первая часть ELF — это описание двоичного файла, поэтому прямо сейчас, когда вы делаете go по первому адресу, вы пытаетесь чтобы указать ЦП выполнить что-то, что не является инструкцией ARM. Вы в основном хотите выполнить то, что мы называем разделом '.text' двоичного файла ELF.

person Mattis Asp    schedule 17.04.2018