Зачем нужна спецификация двоичного формата для исполняемых файлов?

Зачем нужна спецификация двоичного формата для исполняемых файлов?

Я понимаю, что операционная система вроде Linux или Windows написана на языке C/C++ и скомпилирована для определенной архитектуры (например, AMD64) для создания машинного кода, подходящего для этой архитектуры.

Мои вопросы -

  1. Почему для двоичного кода нужна отдельная спецификация — Linux использует ELF, а Windows — Portable Executable Format?
  2. Можно ли создать операционную систему и программу, работающую в этой операционной системе, без этой спецификации двоичного формата?
  3. Зависит ли двоичный формат от архитектуры, ОС или от того и другого?
  4. Применим ли двоичный формат только к исполняемым файлам или он применим также к коду операционной системы?

решение1

Как вы могли догадаться, исполняемые форматы содержат не только машинный код. Например, они могут:

  • Укажите метаданные для ОС, например, для какой архитектуры предназначен исполняемый файл. Эти метаданные включают в себязаголовокфайла.

  • Укажите программумакетв памяти. В современных ОС большинство исполняемых файлов не загружаются в память единым блоком — обычно они имеют много отдельныхрегионы/разделы/сегменты. Некоторые из этих сегментов будут содержать исполняемый код. Некоторые из них будут содержать неизменяемые данные, такие как текстовые строки. Некоторые из них будут обозначены как записываемая память для кучи(ок) программ.

    Разные программы будут иметь разные требования (запросы) к размерам этих разделов. Это все указано в заголовке.

  • Некоторые форматы также позволяют вам встраиватьцифровая подпись, что позволяет проверить, откуда взялся двоичный файл.


  1. Почему для двоичного кода нужна отдельная спецификация — Linux использует ELF, а Windows — Portable Executable Format?

Причины в первую очередь исторические: операционные системы, как правило, придерживаются своего существующего «родного» (или «стандартного») формата, если только нет веской причины для перехода (как это произошло, например, с формата DOS MZ на PE в NT 3.1, с a.out на ELF в Linux 1.2 и с COFF на ELF в различных Unix-системах на протяжении многих лет).

Следует отметить, что базовый машинный код зависит от архитектуры ЦП, но в остальном (за исключением системных вызовов и связанных библиотек) в значительной степени переносим между ОС. Фактически, современные Windows и Linux могут запускать оба формата исполняемых файлов: исполняемые файлы ELF будут запускаться в Windows через WSL, а исполняемые файлы PE будут запускаться в Linux через WINE.

  1. Можно ли создать операционную систему и программу, работающую в этой операционной системе, без этой спецификации двоичного формата?

Возвращаемся к основной цели этих форматов. Без метаданных, сообщающих ОС, куда загружать части программы, большинство современных исполняемых файлов не могут работать. Некоторые очень старые форматы, такие какКОМв основном содержат чистый код, но не отличаются особой гибкостью и вышли из моды.

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

  1. Зависит ли двоичный формат от архитектуры, ОС или и того, и другого?

Зависит от формата, на самом деле. Некоторые форматы предполагают определенную архитектуру. Другие позволяют выбрать архитектуру из списка указанных "магических чисел" в заголовке. Третьи полностью архитектурно-независимы (например, Java и байт-код .NET/CIL).

Аналогично, формат, как правило, не накладывает никаких ограничений на ОС, хотя ОС будет ограничена в том, какие форматы она может (врожденно) распознавать и выполнять. Конечно, слои совместимости поверх основной ОС могут выполнять другие форматы (например, JVM, .NET/CLR, WSL&WINE и т. д.), которые основная ОС может не распознавать.

  1. Применим ли двоичный формат только к исполняемым файлам или он применим и к коду операционной системы?

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

Если привести конкретный, очень распространенный пример, то устаревший загрузчик BIOS будетнетбыть в форматах ELF или PE, используемых Linux и Windows. Ядро Linux обычно строится вФормат, производный от ELFчто загрузчик GRUBможно загрузить, но он может быть в другом формате, чтобы быть совместимым с используемым загрузчиком. Ядро Linux также поддерживаетEFI-заглушкарежим, который содержит минимальный заголовок PE/COFF для совместимости с прямой загрузкой UEFI.

решение2

Основное применение формата — загрузка программ в память, что выполняетсязагрузчик.

  1. Почему для двоичного кода нужна отдельная спецификация — Linux использует ELF, а Windows — Portable Execution Format?

Вежливый ответ: потому что ОС другая и у нее другие требования. Ответ пользователя Unix: потому что Microsoft любит изобретать (квадратный) велосипед.

  1. Можно ли создать операционную систему и программу, работающую в этой операционной системе, без этой спецификации двоичного формата?

Да, но только самые простые, довольно базовая ОС, на которой работают простые программы, которым не нужно «перемещаться» и не нужно связываться с каким-либо внешним кодом.

  1. Зависит ли двоичный формат от архитектуры, ОС или и того, и другого?

Нет, формат ELF используется во многих операционных системах и архитектурах.

  1. Применим ли двоичный формат только к исполняемым файлам или он применим также к коду операционной системы?

В Linux загружаемое ядро ​​может быть не ELF, но модули ядра используют формат ELF.

Связанный контент