У чому різниця між файлами ELF та файлами bin?


97

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


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

Це один з способів , в якому бен файли можуть бути корисні: зробити завантажувальний сектор операційних систем Deploy: stackoverflow.com/a/32483545/895245
Чіро Сантіллі郝海东冠状病六四事件法轮功

Відповіді:


94

Файл Bin - це чисто двійковий файл, у якому немає виправлення та переміщення пам'яті, імовірно, він містить чіткі інструкції щодо завантаження за певною адресою пам'яті. Тоді як ....

Файли ELF - це виконуваний прив'язуваний формат, який складається із пошуку символів та переміщуваної таблиці, тобто його можна завантажувати в будь-яку адресу пам'яті ядром і автоматично всі використовувані символи коригувати до зміщення від адреси пам'яті, де він знаходиться було завантажено в. Зазвичай файли ELF мають ряд розділів, таких як "дані", "текст", "bss", щоб назвати лише декілька ... саме в тих розділах, де час виконання може обчислити, де налаштувати посилання на пам'ять символу динамічно під час виконання.


"з більшою ймовірністю у ньому є чіткі інструкції щодо завантаження за певною адресою пам'яті": чи означає це, що процес генерації файлу bin додає додатковий код для завантаження даних на конкретну адресу?
Penghe Geng

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

@MartinKersten правильний, файли кошика починаються зі зміщення 0.
t0mm13b

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

@BlackyDucky, я не вірю, що це можливо. Якби мікроконтролер намагався виконати дані ELF безпосередньо, він би неправильно інтерпретував заголовки та інші дані як інструкції, так?
jacobq

40

Файл bin - це лише біти та байти, які надходять у rom або на певну адресу, з якої ви будете запускати програму. Ви можете взяти ці дані та завантажити їх безпосередньо як є, вам потрібно знати, яка це базова адреса, хоча, як правило, там немає.

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

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


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

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

1
для голого металу, особливо якщо цей файл elf є завантажувачем та / або першим запуском програми, то точка входу та _start не актуальні, оскільки ви використовуєте файл elf як сходинку до інструменту, який програмує спалах (наприклад, openocd over jtag) або через будь-що-будь-що-objcopy -O двійковий файл.elf file.bin, а потім цей файл якось завантажується у флеш. Не пішов і спробував завантажувач на x86, але припустимо, що bios не може розібрати файли elf, тому це також повинно бути зображенням пам'яті. отже, файл-двійковий тип -O двійкового типу
old_timer

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

1
Щоб розширити те, що у вашої цілі є правила, будь то операційна система, процесор, багатоступеневий завантажувач тощо. І вам потрібно створити свій "двійковий файл", виходячи з цих правил, при цьому найважливішим є завантажувальний файл і linkerscript. Тоді це дуже широко щодо кожної цілі та того, як ви застосовуєте цей двійковий файл та які формати файлів підтримуються. Якщо припустити gnu на багатьох платформах для розробки хостів, формат файлу elf є вихідним за замовчуванням, і тоді ви використовуєте інструменти за необхідності (якщо цільові утиліти / завантажувачі) для вилучення або перетворення з elf на щось інше.
old_timer

30

деякі ресурси:

  1. ELF для архітектури ARM
    http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
  2. ELF з wiki
    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 створюється Linker, а не компілятором.

Місія компілятора закінчується після створення об'єктних файлів (* .o) з файлів вихідного коду. Linker пов'язує всі файли .o разом і створює ELF.


Проголосовано проти, оскільки воно не відповідає на запитання і не обов’язково правильне. Широко визначена компіляція включає посилання. Цитується з ldдокументації : Зазвичай останнім кроком при складанні програми є запуск ld.
bzeaman
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.