Jaka jest różnica między plikami ELF a plikami bin?

99

Końcowe obrazy utworzone przez autorów zgodności zawierają zarówno plik bin, jak i plik ELf w formacie rozszerzonego modułu ładującego, jaka jest różnica między nimi, zwłaszcza użyteczność pliku ELF.

Manik Mahajan
źródło
To właśnie ma do powiedzenia NASM . Nie dotyczy ARM, ale prawdopodobnie będzie to ta sama koncepcja. Na przykład, jeśli kompilujesz plik zawierający tylko NOPbez -f(lub -fbin), kompiluje się on do pojedynczego bajtu 0x90, zamiast do 400-bajtowego kontenera ELF z -felf32. Więc tylko surowy kod, bez metadanych kontenera. NASM twierdzi, że jest używany głównie do plików MS-DOS .COM i .SYS . sectiondyrektywy są przeważnie ignorowane i tylko generują wyrównanie.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Oto jeden ze sposobów, w jaki pliki bin mogą być przydatne: aby utworzyć sektor startowy do wdrażania systemów operacyjnych: stackoverflow.com/a/32483545/895245
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

94

Plik Bin jest czystym plikiem binarnym bez poprawek pamięci lub relokacji, najprawdopodobniej zawiera wyraźne instrukcje do załadowania pod określony adres pamięci. Natomiast....

Pliki ELF to wykonywalny format, który można połączyć, który składa się z wyszukiwania symboli i tabeli relokowalnej, to znaczy może być ładowany na dowolny adres pamięci przez jądro i automatycznie, wszystkie używane symbole są dostosowywane do przesunięcia z tego adresu pamięci, w którym się znajdują został załadowany do. Zwykle pliki ELF mają wiele sekcji, takich jak `` dane '', `` tekst '', `` bss '', aby wymienić tylko kilka ... to w tych sekcjach środowisko wykonawcze może obliczyć, gdzie dostosować odwołania do pamięci symbolu dynamicznie w czasie wykonywania.

t0mm13b
źródło
„najprawdopodobniej ma wyraźne instrukcje do załadowania pod konkretnym adresem pamięci”: czy oznacza to, że proces generowania pliku bin dodaje dodatkowy kod do ładowania danych pod określony adres?
Penghe Geng
1
O ile się dowiedziałem, plik bin jest jak uruchomienie programu od offsetu 0, a segment danych jest osadzony w nim. Jeśli to źle, proszę mnie poprawić.
Martin Kersten,
@MartinKersten poprawnie, pliki bin zaczynają się od przesunięcia 0.
t0mm13b
1
@ t0mm13b Czyli pliki .elf można nagrać na mikrokontrolerze, tak jak zwykły plik .hex, ale zajmuje to więcej pamięci flash, a za każdym razem, gdy micro jest resetowany, adresy sekcji się zmieniają?
Aelgawad
@BlackyDucky, nie wierzę, że jest to możliwe. Gdyby mikrokontroler próbował bezpośrednio wykonać dane ELF, błędnie zinterpretowałby nagłówki i inne dane jako instrukcje, prawda?
jacobq
40

Plik bin to tylko bity i bajty, które trafiają do pamięci ROM lub określonego adresu, z którego uruchomisz program. Możesz pobrać te dane i załadować je bezpośrednio w obecnej postaci, ale musisz wiedzieć, jaki jest adres bazowy, ponieważ zwykle go tam nie ma.

Plik elf zawiera informacje bin, ale jest otoczony wieloma innymi informacjami, możliwymi informacjami debugowania, symbolami, które mogą odróżnić kod od danych w pliku binarnym. Pozwala na więcej niż jedną porcję danych binarnych (kiedy zrzucisz jeden z nich do kosza, otrzymasz jeden duży plik bin z danymi wypełnienia, aby dopełnić go do następnego bloku). Informuje, ile masz plików binarnych i ile jest danych bss, które chcą zostać zainicjalizowane do zera (narzędzia gnu mają problemy z poprawnym tworzeniem plików bin).

Format pliku elf jest standardem, ramię publikuje swoje ulepszenia / odmiany w standardzie. Zalecam każdemu napisanie programu do analizy elfów, aby zrozumieć, co się w nim znajduje, nie przejmuj się biblioteką, po prostu skorzystaj z informacji i struktur w specyfikacji. Pomaga przezwyciężyć problemy z GNU w tworzeniu plików .bin, a także debugować skrypty linkera i inne rzeczy, które mogą zepsuć wyjście bin lub elf.

old_timer
źródło
1
0x7C00 brzmi jak bootloader, który niekoniecznie używa elfa. to jest ogólne pytanie. system operacyjny miałby reguły dla (wirtualnych) przestrzeni adresowych, łańcuch narzędzi musiałby być ukierunkowany na te reguły systemu operacyjnego, a następnie format pliku wskazywałby na ładowane elementy z adresami, punkt wejścia po załadowaniu i inne rzeczy. elf to tylko pojemnik, jak pudełko, musisz go spakować odpowiednio do docelowego przypadku użycia.
old_timer
1
jeśli chcesz wydrukować jakieś ascii do VGA, piszesz program, który robi to, który ma jakieś dane lub matematycznie generuje dane w locie lub jakąś kombinację, następnie ładujesz ten program do przestrzeni kodu zdefiniowanej przez system operacyjny, a następnie uruchamiasz to. generalnie nie umieszcza się danych bezpośrednio na fizycznym urządzeniu peryferyjnym, a jest to rzadki system operacyjny, który i tak by na to pozwolił lub pozwalał na to programowi ładującemu.
old_timer
1
dla gołego metalu, szczególnie jeśli ten plik elf jest bootloaderem i / lub pierwszym uruchomieniem programu, to punkt wejścia i _start nie są istotne, ponieważ używasz pliku elf jako odskoczni do narzędzia, które programuje flash (jak openocd przez jtag) lub przez cokolwiek-cokolwiek-objcopy -O plik binarny.elf plik.bin, a następnie ten plik jest w jakiś sposób ładowany do pamięci flash. Nie poszedł i nie wypróbował bootloadera na x86, ale załóżmy, że bios nie może analizować plików elf, więc musiałby to być również obraz pamięci. więc plik bin typu binarnego -O
old_timer
1
oddzielną jednostką jest sprzęt / logika lub inny projekt. dla systemów operacyjnych to system operacyjny tworzy reguły, dla mikrokontrolera to konstrukcja chipa / procesora tworzy reguły. na przykład, jeśli istnieje tablica wektorów, a następnie wektory wskazują programy obsługujące, musisz przenieść to wszystko do skryptu konsolidatora itp., aby ładowane dane były przeznaczone dla pamięci flash, z której urządzenie się uruchamia.
old_timer
1
Aby poszerzyć, twój cel ma reguły, czy to system operacyjny, procesor, czy wielostopniowy program ładujący, itd. I musisz zbudować swój „plik binarny” w oparciu o te reguły, z których najważniejszy jest bootstrap i linkerscript. Następnie jest bardzo obszerny, jeśli chodzi o każdy cel, sposób zastosowania tego pliku binarnego i obsługiwane formaty plików. Zakładając, że GNU na wielu platformach programistycznych hosta, format pliku elf jest domyślnym wyjściem, a następnie używasz narzędzi w razie potrzeby (jeśli docelowe narzędzia / programy ładujące), aby wyodrębnić lub przekonwertować z elfa na coś innego.
old_timer
30

niektóre zasoby:

  1. ELF dla architektury ARM
    http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
  2. ELF z wiki
    http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

Format ELF jest ogólnie domyślnym wynikiem kompilacji. jeśli używasz łańcuchów narzędzi GNU, możesz przetłumaczyć je na format binarny za pomocą objcopy, na przykład:

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

lub używając narzędzia fromELF (wbudowanego w większość IDE, takich jak ADS):

 fromelf -bin -o [binary-output-file] [elf-input-file]
wenlujon
źródło
6
Zostało to dodane po udzieleniu odpowiedzi na szczegóły dotyczące pliku bin i stanowi uzupełnienie praktycznie użytecznej techniki. +1 za to.
erbdex
-1

Chcę tylko poprawić tutaj punkt. Plik ELF jest tworzony przez konsolidatora, a nie przez kompilator.

Misja kompilatora kończy się po utworzeniu plików obiektowych (* .o) z plików kodu źródłowego. Linker łączy wszystkie pliki .o razem i tworzy ELF.

Ahmed Gamal
źródło
Negocjowany, ponieważ nie odpowiada na pytanie ani nie musi być poprawny. Ogólnie rzecz biorąc, kompilacja obejmuje linkowanie. Cytat z lddokumentacji : Zwykle ostatnim krokiem kompilacji programu jest uruchomienie ld.
bzeaman