Как может ядро ​​Linux скомпилировать себя?

Я не совсем понимаю процесс компиляции ядра Linux при установке Linux на моей машине.

Вот некоторые вещи, которые меня смутили:

  • Ядро написано на C, однако как было скомпилировано ядро ​​без компилятора?
  • Если компилятор C установлен на моем компьютере до того, как ядро ​​скомпилировано, как сам компилятор может быть скомпилирован без установленного компилятора?

Я был так смущен в течение нескольких дней, спасибо за ответ.

Ответ 1

Первый раунд двоичных файлов для вашего Linux-бокса был построен на другом Linux-поле (возможно).

Бинарные файлы для первой системы Linux были построены на другой платформе.

Двоичные файлы для этого компьютера могут отследить их корень до исходной системы, которая была построена на еще одной платформе.

...

Надавите на это достаточно далеко, и вы найдете компиляторы, созданные с использованием более простых инструментов, которые, в свою очередь, были созданы на машинах, отличных от их хоста.

...

Продолжайте нажимать, и вы обнаружите, что компьютеры построены так, что их команды могут быть введены с помощью переключателей на передней панели устройства.

Очень классный материал.

Правило: "Создайте инструменты для создания инструментов для создания инструментов...". Очень похоже на инструменты, которые управляют нашей физической средой. Также известен как "потянув себя за бутстрапы".

Ответ 2

Я думаю, вы должны различать:

компилировать, v: использовать компилятор для обработки исходного кода и создания исполняемого кода [1].

и

установить, v: подключиться, настроить или подготовить что-то для использования [2].

Компиляция создает двоичные исполняемые файлы из исходного кода. Установка просто помещает эти двоичные исполняемые файлы в нужное место, чтобы запустить их позже. Таким образом, установка и использование не требуют компиляции, если доступны двоичные файлы. Подумайте об "компиляции" и "установке", например, о "cook" и "serve", соответственно.

Теперь ваши вопросы:

  • Ядро написано на C, однако как было скомпилировано ядро ​​без компилятора?

Ядро нельзя компилировать без компилятора, но его можно установить из скомпилированного двоичного файла.

Обычно, когда вы устанавливаете операционную систему, вы устанавливаете предварительно скомпилированное ядро ​​(двоичный исполняемый файл). Он был составлен кем-то другим. И только если вы хотите скомпилировать ядро ​​самостоятельно, вам понадобятся источник и компилятор, а также все другие инструменты.

Даже в "исходных" дистрибутивах, таких как gentoo, вы запускаете скомпилированный двоичный файл.

Итак, вы можете прожить всю свою жизнь без компиляции ядер, потому что вы их скомпилировали кем-то другим.

  1. Если компилятор C установлен на моем компьютере до того, как ядро ​​скомпилировано, как сам компилятор может быть скомпилирован без установленного компилятора?

Компилятор не может быть запущен, если нет ядра (ОС). Таким образом, нужно установить скомпилированное ядро ​​для запуска компилятора, но ему не нужно самому скомпилировать ядро.

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

Теперь проблема с курицей и яйцом. Первый двоичный файл компилируется кем-то другим... См. Отличный ответ dmckee.

Ответ 3

Термин, описывающий это явление, bootstrapping, это интересная концепция для чтения. Если вы думаете о встроенной разработке, становится ясно, что многие устройства, например будильники, микроволновые печи, пульты дистанционного управления, которые требуют программного обеспечения, недостаточно сильны для компиляции собственного программного обеспечения. На самом деле, эти устройства обычно не имеют достаточных ресурсов для запуска чего-либо удаленно сложного, как компилятор.

Их программное обеспечение разработано на настольной машине, а затем скопировано после его компиляции.

Если это вас интересует, статья, которая приходит на ум с моей головы, выглядит следующим образом: Размышления о Trusting Trust (pdf), это классическое и забавное чтение.

Ответ 4

Ядро не компилируется - оно скомпилировано компилятором C в пользовательском пространстве. В большинстве архитектур процессоров ЦПУ имеет несколько бит в специальных регистрах, которые представляют, какие привилегии имеют текущий код. В x86 это текущие биты уровня привилегий (CPL) в регистре сегмента кода (CS). Если бит CPL равен 00, этот код, как говорят, работает в защитном кольце 0, также известном как режим ядра. Если биты CPL равны 11, этот код, как говорят, работает в защитном кольце 3, также известном как пользовательский режим. Две другие комбинации, 01 и 10 (защитные кольца 1 и 2 соответственно) используются редко.

Правила о том, что код может и не может делать в режиме пользователя в зависимости от режима ядра, довольно сложны, но достаточно сказать, что пользовательский режим сильно уменьшил привилегии.

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

Компилятор C является одним из примеров такой программы - для него не нужны дополнительные привилегии, предлагаемые режимом ядра, поэтому он запускается в пользовательском режиме, как и большинство других программ.

В случае Linux ядро ​​состоит из двух частей: исходного кода ядра и скомпилированного исполняемого файла ядра. Любая машина с компилятором C может скомпилировать ядро ​​из исходного кода в двоичное изображение. Тогда возникает вопрос, что делать с этим двоичным образом.

Когда вы устанавливаете Linux в новую систему, вы устанавливаете предварительно скомпилированное двоичное изображение, как правило, с любого физического носителя (например, CD DVD) или из сети. BIOS загрузит загрузчик ядра (бинарное изображение) с носителя или сети, а затем загрузчик установит (двоичное изображение) ядро ​​на ваш жесткий диск. Затем, когда вы перезагружаетесь, BIOS загружает загрузчик ядра с вашего жесткого диска, а загрузчик загружает ядро ​​в память, и вы выключены и запущены.

Если вы хотите перекомпилировать свое собственное ядро, это немного сложнее, но это можно сделать.

Ответ 5

Какой из них был первым? курица или яйцо?

Яйца были со времен динозавров.

.. некоторые путают все, говоря, что цыплята на самом деле являются потомками великих зверей. Короче говоря: технология (яйцо) существовала до текущего продукта (курица)

Вам нужно ядро ​​для сборки ядра, т.е. вы создадите его с другим.

Первое ядро ​​может быть любым, что вы хотите (желательно что-то разумное, которое может создать желаемый конечный продукт ^ __ ^)

Этот учебник от Bran Kernel Development учит вас разрабатывать и создавать небольшое ядро, которое вы можете проверить с помощью виртуальной машины по вашему выбору.

Смысл: вы пишете и компилируете ядро ​​где-то и читаете его на пустой (без ОС) виртуальной машине.

Что происходит с этими установками Linux, следует той же идее с дополнительной сложностью.

Ответ 6

Это не черепахи полностью вниз. Как и вы говорите, вы не можете скомпилировать операционную систему, которая никогда не была скомпилирована ранее в системе, работающей с этой операционной системой. Точно так же, по крайней мере, самая первая сборка компилятора должна быть выполнена на другом компиляторе (и, как правило, на некоторых последующих сборках тоже, если эта первая сборка оказывается неспособной еще скомпилировать собственный исходный код).

Я думаю, что первые ядра Linux были скомпилированы в окне Minix, хотя я не уверен в этом. GCC был доступен в то время. Одной из самых ранних целей многих операционных систем является достаточно быстрый запуск компилятора для компиляции собственного исходного кода. Идем дальше, первый компилятор почти наверняка написан на ассемблере. Первые ассемблеры были написаны теми бедными людьми, которым пришлось писать в сыром машинный код.

Вы можете проверить проект Linux From Scratch. Фактически вы создаете две системы в книге: "временная система", которая построена на системе, которую вы не создали самостоятельно, а затем "система LFS", которая построена на вашей временной системе. То, как книга в настоящее время написана, вы фактически создаете временную систему на другом Linux-боксе, но теоретически вы можете ее адаптировать для создания временной системы на совершенно другой ОС.

Ответ 7

Если я правильно понимаю ваш вопрос. В наши дни ядро ​​не "компилируется". В настоящее время большинство дистрибутивов Linux обеспечивают установку системы через live cd. Ядро загружается с компакт-диска в память и работает так, как если бы оно было установлено на диск. С помощью linux-среды, запущенной в вашей системе, легко просто передать необходимые файлы на ваш диск.

Если вы говорили о проблеме начальной загрузки; dmckee суммировал его довольно приятно.

Просто предлагаю другую возможность...