3.12. Бинарни формати

За да разберете защо FreeBSD използва elf(5) форматът първо трябва да научите малко за трите ``доминиращи'' изпълними формати за UNIX®:

FreeBSD идва от ``класическия'' лагер и използваше a.out(5) формат, технология доказала се чрез много издания на BSD, до началото на 3.X бранш. Въпреки, че беше възможно компилирането на ELF бинарни файлове (и ядра) на FreeBSD система от доста време преди това, FreeBSD отначало се съпротивляваше на ``натиска'' да премине към ELF като формат по подразбиране. Защо? Ами защото Linux лагера направи болезнения преход към ELF, не толкова заради отхвърлянето на a.out изпълнимия формат, колкото заради неудобния механизъм на скачаща-таблица за поделени библиотеки, което правеше конструирането на поделени библиотеки много трудно за доставчици и разработчици. Понеже инструментите са ELF предлагаха решение на проблема с поделени библиотеки и на тях се гледаше като ``пътя напред'', цената на мигрирането беше приета и прехода направен. Механизмът за поделени библиотеки на FreeBSD е базиран повече на стила на Sun SunOS™ и поради това е много лесен за използване.

Все пак, защо има толкова различни формати?

В онова тъмно и мрачно мрачно минало имаше прост хардуер. Това беше прост хардуер поддържащ прости малки системи. a.out беше напълно адекватен за работата да представя бинарни файлове на тези прости системи (a PDP-11). След като хора преработиха UNIX от тази проста система, те запазиха a.out формата защото той беше достатъчен за ранните портове на UNIX за архитектури като Motorola 68k, VAXen, е т.н.

Тогава умен хардуерен инженер реши, че ако може да принуди хардуера да прави някои мръсни трикове, тогава ще може да премахне някои неща от дизайна и да позволи процесора да работи по-бързо. Въпреки, че беше направен да работи с този нов хардуер (познат по онова време като RISC), a.out не беше здравословен за този хардуер, което доведе до разработката на няколко формата предоставящи по-добра производителност от колкото сравнително ограничения прост a.out. Неща като COFF, ECOFF, и още няколко други бяха разработени и техните ограничения открити докато нещата се уталожиха с ELF.

В допълнение, размерът на програмите ставаше огромен а дисковете (а и физическата памет) бяха все още относително малки така че се роди концепцията за поделени библиотеки. Виртуалната машина (VM) също стана доста по-сложна. Макар че, всички тези нововъведения бяха направени с помощта на a.out формата, той беше разтеглян все повече и повече. В допълнение хората искаха динамично зареждане на неща по време на изпълнение, или да могат да освободят част от паметта заемана от програмата им след началната инициализация за да спестят основна памет и поделено пространство (swap). Езиците ставаха все по-усложнени и хората искаха програмен код да може да се извиква преди main автоматично. Много корекции бяха направени на a.out формата за да са възможни всички тези неща, и в общи линии те работеха. С времето ставаше невъзможно да се коригират всички тези проблеми без никакво усложняване на кода. Докато ELF решаваше много от тях, би било болезнено да се премине към него от системата, която макар и стара работеше добре. Така, че, ELF трябваше да почака докато станеше по-болезнено да се работи с a.out отколкото да се мигрира към ELF.

С течение на времето, инструментите от които FreeBSD беше изградило инструменти за изграждане (assembler и loader) еволюираха в две паралелни разклонения. FreeBSD добави поддръжка за поделени библиотеки и оправи няколко проблема. Хората от GNU които оригинално бяха написали тези инструменти ги пренаписаха и добавиха тяхна собствена поддръжка за изграждане на компилатори, с добавена поддръжка за различни формати и т.н. Понеже много хора искаха да изграждат крос-компилатори за FreeBSD, те бяха без късмет поради по-старите изходни кодове които FreeBSD използваше за as и ld. Набора от новите GNU инструменти (binutils) поддържаше крос-компилиране, ELF, поделени библиотеки, C++ разширения и т.н. В допълнение много доставчици издават ELF бинарни файлове и е добре FreeBSD да може да ги стартира.

ELF е по-изразителен от a.out и позволява по-голяма разширяемост в базовата система. ELF инструментите се поддържат по-добре и предлагат по-добър крос-компилаторна поддръжка, което е важно за работата на много хора. ELF може да е малко по-бавен от a.out, но да се получи точна оценка е малко трудно. Има изключително много детайли които са различни между тези два формата - как се позиционират страници, манипулатори, инициализиращ код и т.н. Тези детайли не са много важни за момента, но има разлики. С времето поддръжката за a.out ще бъде премахната от GENERIC ядрото и евентуално премахната напълно от ядрото когато нуждата да се стартират a.out програми е в миналото.

Този и други документи можете да намерите в ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

За въпроси относно FreeBSD, прочетете документацията преди да попитате в <questions@FreeBSD.org>.
За въпроси относно този документ, e-mail <doc@FreeBSD.org>.