В чем разница между файлами ELF и файлами bin?


99

Окончательные изображения, созданные разработчиками, содержат как файл bin, так и файл ELF расширенного формата загрузчика, в чем разница между ними, особенно полезность файла ELF.


Вот что говорит NASM . Не для ARM, но, скорее всего, это та же концепция. Например, если вы скомпилировать файл , содержащий только NOPбез -f(или -fbin), он собирает в один байт 0x90, вместо 400 байт ELF контейнера с -felf32. Так что только необработанный код, без метаданных контейнера. NASM утверждает, что он в основном используется для файлов MS-DOS .COM и .SYS . sectionдирективы в основном игнорируются и только генерируют выравнивание.
Чиро Сантилли 郝海东 冠状 病 六四 事件 法轮功

Это один из способов использования bin-файлов: создание загрузочного сектора для развертывания операционных систем: stackoverflow.com/a/32483545/895245
Ciro Santilli 郝海东 冠状 病 六四

Ответы:


94

Файл Bin - это чистый двоичный файл без исправлений или перемещений памяти, более чем вероятно, что у него есть явные инструкции для загрузки по определенному адресу памяти. В то время как....

Файлы ELF представляют собой исполняемый связываемый формат, который состоит из поиска символов и перемещаемой таблицы, то есть они могут быть загружены ядром по любому адресу памяти, и автоматически все используемые символы настраиваются на смещение от того адреса памяти, где он был загружен в. Обычно файлы ELF имеют несколько разделов, таких как 'data', 'text', 'bss', и это лишь некоторые из них ... именно в тех разделах, где среда выполнения может вычислить, где настроить ссылки на память символа. динамически во время выполнения.


«более чем вероятно, что у него есть явные инструкции для загрузки по определенному адресу памяти»: означает ли это, что процесс генерации файла bin добавляет дополнительный код для загрузки данных по определенному адресу?
Penghe Geng

1
Насколько я понял, файл bin похож на запуск программы со смещения 0, а сегмент данных встроен внутрь. Если это не так, пожалуйста, поправьте меня.
Мартин Керстен

@MartinKersten правильно, файлы bin начинаются со смещения 0.
t0mm13b 01

1
@ t0mm13b Значит, файлы .elf можно записывать на микроконтроллер, как обычный файл .hex, но для этого требуется больше флэш-памяти, и каждый раз, когда микроконтроллер сбрасывается, адреса разделов меняются?
Aelgawad

@BlackyDucky, я не верю, что это возможно. Если бы микроконтроллер попытался выполнить данные ELF напрямую, он бы неправильно интерпретировал заголовки и другие данные как инструкции, верно?
jacobq

40

Файл bin - это просто биты и байты, которые входят в ROM или конкретный адрес, с которого вы будете запускать программу. Вы можете взять эти данные и загрузить их напрямую как есть, но вам нужно знать, что такое базовый адрес, поскольку его обычно там нет.

Файл elf содержит информацию о бункере, но он окружен множеством другой информации, возможной отладочной информацией, символами, которые могут отличать код от данных в двоичном файле. Позволяет использовать более одного фрагмента двоичных данных (когда вы сбрасываете один из них в корзину, вы получаете один большой файл корзины с данными для заполнения, чтобы добавить его к следующему блоку). Сообщает вам, сколько у вас двоичных файлов и сколько там данных bss, которые нужно инициализировать нулями (у инструментов GNU есть проблемы с правильным созданием файлов bin).

Формат файла elf является стандартным, arm публикует его улучшения / вариации по стандарту. Я рекомендую всем написать программу синтаксического анализа elf, чтобы понять, что там есть, не беспокойтесь о библиотеке, довольно просто просто использовать информацию и структуры в спецификации. Помогает преодолеть проблемы GNU в целом при создании файлов .bin, а также отладке сценариев компоновщика и других вещей, которые могут помочь испортить ваш bin или elf вывод.


1
0x7C00 звучит как загрузчик, который не обязательно использует elf. это общий вопрос. операционная система будет иметь правила для (виртуальных) адресных пространств, цепочка инструментов должна быть нацелена на эти правила операционной системы, тогда формат файла будет указывать на загружаемые элементы с адресами плюс точку входа после загрузки, а также другие вещи. elf - это просто контейнер, как коробка, вы должны упаковать его правильно для целевого варианта использования.
old_timer

1
если вы хотите напечатать некоторый ascii в vga, вы пишете программу для выполнения того, что имеет некоторые данные или математически генерирует данные на лету или в некоторой комбинации, затем вы загружаете эту программу в пространство кода, определенное операционной системой, а затем запускаете Это. вы обычно не засовываете данные прямо в физическое периферийное устройство, и это редкая операционная система, которая позволяет вам делать это в любом случае или позволяет загрузчику делать это.
old_timer

1
для голого металла, особенно, если этот файл elf является загрузчиком и / или первым запуском программы, то точка входа и _start не имеют значения, поскольку вы используете файл elf как ступеньку к инструменту, который программирует флэш (например, openocd over jtag) или через файл Any-any-objcopy -O binary file.elf file.bin, а затем этот файл каким-то образом загружается во флэш-память. Не пошел и не попробовал загрузчик на x86, но предполагаю, что BIOS не может анализировать файлы elf, поэтому это также должен быть образ памяти. так что бинарный файл двоичного типа -O
old_timer

1
отдельный объект - это оборудование / логика или другой дизайн. для операционных систем операционная система устанавливает правила, для микроконтроллера - дизайн микросхемы / процессора. например, если есть таблица векторов, а затем векторы указывают на обработчики, вы должны перенести все это в свой сценарий компоновщика и т.д., чтобы загружаемые данные предназначались для флэш-памяти, из которой загружается вещь.
old_timer

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

30

некоторые ресурсы:

  1. ELF для архитектуры ARM
    http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
  2. ELF из вики
    http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

Формат ELF обычно является результатом компиляции по умолчанию. если вы используете цепочки инструментов GNU, вы можете перевести их в двоичный формат с помощью objcopy, например:

  arm-elf-objcopy -O binary [elf-input-file] [binary-output-file]

или с помощью утилиты fromELF (хотя она встроена в большинство IDE, таких как ADS):

 fromelf -bin -o [binary-output-file] [elf-input-file]

6
Это было добавлено после того, как были даны ответы на детали bin-файла, и оно является практически полезным методом. +1 за это.
erbdex

-1

Я просто хочу исправить здесь один момент. Файл ELF создается компоновщиком, а не компилятором.

Миссия компилятора заканчивается после создания объектных файлов (* .o) из файлов исходного кода. Компоновщик связывает все файлы .o вместе и создает ELF.


Проголосовали против, потому что это не отвечает на вопрос и не обязательно правильно. В широком смысле компиляция включает связывание. Цитата из ldдокументации : Обычно последний шаг в компиляции программы - это запуск ld.
bzeaman
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.