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

89

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

Вот что меня смутило:

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

Пару дней так растерялась, спасибо за ответ.

MainID
источник
Насколько известно, C-компилятор был написан каким-то сумасшедшим и умным парнем из лабораторий AT&T для компиляции UNIX для данного компьютера (обратите внимание, что история началась с UNIX, а не с Linux, так что я боюсь, что вы пропустите главу ... или несколько из них!). Коротко говоря, не было необходимости переписывать ядро ​​unix для разных компьютеров, если на этих компьютерах есть соответствующий компилятор для языка C. Эти компиляторы были написаны на конкретном ассемблере целевых компьютеров. Грубое высказывание: «Сначала компилятор написан на ассемблере данного компьютера, затем UNIX написан на C»
Виктор

Ответы:

208

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

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

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

...

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

...

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

Очень классная штука.

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

dmckee --- котенок экс-модератора
источник
3
Не обязательно нечистым. Просто неоптимизировано. первый компилятор будет оптимизирован для работы на 386, но перекомпилированная версия будет оптимизирована для любой вашей архитектуры.
Breton
1
Вы можете добавить третью ступень, если все в порядке, мощность второй ступени должна быть равна мощности третьей ступени.
Ismael
27
Это не просто программное обеспечение, это оборудование. Невозможно построить что-нибудь вроде P4 (или даже 486) без компьютера.
BCS
1
@BCS: О да. Мы достигли точки, когда программные и аппаратные средства глубоко взаимосвязаны и взаимозависимы.
dmckee --- котенок экс-модератора
4
«Сложная работающая система неизменно эволюционировала из простой работающей системы». en.wikipedia.org/wiki/Gall's_law
ajuc
33

Я думаю, вам следует различать:

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

а также

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

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

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

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

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

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

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

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

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

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

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

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

састанин
источник
14

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

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

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

a2800276
источник
1
Вы путаете кросс-компиляцию с начальной загрузкой. Первый связан с компилятором, который существует только на ПК и который создает коды операций для целевой архитектуры. Очевидно, вы не сможете сделать это без другого компьютера, поэтому возникает дилемма курицы и яйца. Ответом на дилемму является самонастройка, при которой рукописный или уже существующий простой компилятор используется для создания более сложного компилятора.
Кевин Вермеер
12

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

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

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

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

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

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

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

Адам Розенфилд
источник
5

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

Яйца существуют еще со времен динозавров.

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

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

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

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

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

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

Рик Токио
источник
5

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

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

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

Самый ложный
источник
1

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

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

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

дюйм70x
источник