Linuxカーネルはどのようにしてそれ自体をコンパイルできますか?


88

自分のマシンにLinuxシステムをインストールしたときのLinuxカーネルのコンパイルプロセスがよくわかりません。

ここに私を混乱させたいくつかのものがあります:

  1. カーネルはCで書かれていますが、コンパイラをインストールせずにカーネルをコンパイルするにはどうすればよいですか?
  2. カーネルをコンパイルする前にCコンパイラをマシンにインストールした場合、コンパイラをインストールせずにコンパイラ自体をコンパイルするにはどうすればよいですか?

返事をありがとう、私は数日間とても混乱しました。


Cコンパイラは、AT&Tラボのクレイジーで賢い人々によって、特定のコンピュータ用にUNIXをコンパイルするために、ある種のアサンブラで記述されていました(歴史はLinuxではなくUNIXから始まっているので、恐れています)章を欠く...またはそれらのいくつか!)短所は、それらのコンピューターがC言語用の適切なコンパイラーを備えている限り、異なるコンピューター用のUNIXカーネルを書き直す必要がなかったことです。これらのコンパイラは、ターゲットコンピュータの特定のアサンブラで記述されています。「最初のコンパイラは特定のコンピュータのアサンブラで記述され、次にUNIXはCで記述された」
ビクター

回答:


208

Linuxボックスのバイナリの最初のラウンドは、おそらく他のLinuxボックス上に構築されました。

最初のLinuxシステムのバイナリは、他のプラットフォームで構築されました。

そのコンピュータのバイナリは、さらに別のプラットフォームで構築された元のシステムまで、ルートをたどることができます。

...

これを十分に押し出すと、より原始的なツールでビルドされたコンパイラーが見つかり、それらはホスト以外のマシンでビルドされました。

...

押し続けると、マシンのフロントパネルにあるスイッチを設定して指示を入力できるように構築されたコンピューターが見つかります。

とてもクールなもの。

ルールは、「ツールを構築するためのツールを構築する...」です。物理環境を実行するツールとよく似ています。「ブートストラップによって自分を引き上げる」とも呼ばれます。


3
必ずしも汚れているとは限りません。最適化されていません。最初のコンパイラは386で動作するように最適化されますが、再コンパイルされたバージョンは、どのようなアーキテクチャでも最適化されます。
ブルトン語

1
すべてが問題なければ、2番目のステージの出力は3番目のステージの出力と等しくなければなりません。
イスマエル

27
それはソフトウェアだけでなく、ハードウェアでもあります。P4(または486)のようなものをコンピューターなしで構築する方法はありません。
BCS

1
@BCS:ああ、そうです。ソフトウェアとハ​​ードウェアのツールが深く相互に関連し、相互依存しているという点に到達しました。
dmckee ---元モデレーターの子猫

4
「機能する複雑なシステムは、機能する単純なシステムから進化したものであることが必ずわかります。」en.wikipedia.org/wiki/Gall's_law
2013

33

以下を区別する必要があると思います。

compile、v:コンパイラを使用してソースコードを処理し、実行可能コードを生成します[1]

そして

インストール、v:接続、セットアップ、または使用するための準備[2]

コンパイルは、ソースコードからバイナリ実行可能ファイルを生成します。インストールは、それらのバイナリ実行可能ファイルを後で実行するための適切な場所に配置するだけです。したがって、バイナリが利用可能であれば、インストールと使用にコンパイルは必要ありません。「cook」や「serve」のように、「コンパイル」や「インストール」も同様に考えてください。

さて、あなたの質問:

  1. カーネルはCで書かれていますが、コンパイラをインストールせずにカーネルをコンパイルするにはどうすればよいですか?

カーネルはコンパイラなしではコンパイルできませんが、コンパイルされたバイナリからインストールできます。

通常、オペレーティングシステムをインストールするときに、事前にコンパイルされたカーネル(バイナリ実行可能ファイル)をインストールします。他の誰かによって編集されました。カーネルを自分でコンパイルする場合にのみ、ソースとコンパイラ、およびその他すべてのツールが必要です。

gentooのような「ソースベース」のディストリビューションでも、コンパイルされたバイナリの実行から始めます。

したがって、カーネルをコンパイルすることなく、他の誰かによってコンパイルされているため、生涯を過ごすことができます。

  1. カーネルをコンパイルする前にCコンパイラをマシンにインストールした場合、コンパイラをインストールせずにコンパイラ自体をコンパイルするにはどうすればよいですか?

カーネル(OS)がない場合、コンパイラーは実行できません。したがって、コンパイラを実行するにはコンパイル済みカーネルをインストールする必要がありますが、カーネルを自分でコンパイルする必要はありません。

繰り返しますが、最も一般的な方法は、コンパイラのコンパイル済みバイナリをインストールし、それらを使用して他のもの(コンパイラ自体とカーネルを含む)をコンパイルすることです。

今、鶏と卵の問題。最初のバイナリは他の誰かによってコンパイルされています... dmckeeによるすばらしい答えを見てください。


14

この現象を説明する用語はブートストラップであり、読み進めるのは興味深い概念です。組み込み開発について考えると、ソフトウェアを必要とする多くのデバイス(目覚まし時計、電子レンジ、リモコンなど)は、独自のソフトウェアをコンパイルするのに十分強力ではないことが明らかになります。実際、これらの種類のデバイスには、通常、コンパイラのように複雑なものをリモートで実行するための十分なリソースがありません。

彼らのソフトウェアはデスクトップマシンで開発され、コンパイルされたらコピーされます。

この種のことに興味があるなら、頭の中で頭に浮かぶ記事は次のとおりです。Reflectionon Trusting Trustpdf)、それは古典的で楽しい読み物です。


1
クロスコンパイルとブートストラップを混同している。1つ目は、PCにのみ存在し、ターゲットアーキテクチャ用のオペコードを作成するコンパイラーです。言うまでもなく、別のコンピューターなしではこれを行うことはできないため、鶏と卵のジレンマがあります。ジレンマへの答えは、ブートストラップです。ここでは、手書きまたは既存の単純なコンパイラーを使用して、より複雑なコンパイラーを生成します。
ケビンフェルメール

12

カーネルはそれ自体をコンパイルしません-ユーザー空間でCコンパイラによってコンパイルされます。ほとんどのCPUアーキテクチャーでは、CPUは、現在実行中のコードがどのような特権を持っているかを表す特別なレジスターにいくつかのビットがあります。x86では、これらは現在の特権レベルですコードセグメント(CS)レジスタビット(CPL)です。CPLビットが00の場合、コードはカーネルモードとも呼ばれるセキュリティリング0で実行されていると言います。CPLビットが11の場合、コードは、ユーザーモードとも呼ばれるセキュリティリング3で実行されていると言います。他の2つの組み合わせ01と10(それぞれセキュリティリング1と2)はほとんど使用されません。

ユーザーモードとカーネルモードで実行できるコードと実行できないコードに関するルールはかなり複雑ですが、ユーザーモードでは特権が大幅に削減されていると言えます。

さて、人々がオペレーティングシステムのカーネルについて話すとき、彼らは、昇格された特権でカーネルモードで実行されるOSのコードの部分を指しています。一般に、カーネルの作成者は、セキュリティ上の理由からカーネルをできるだけ小さくしようとします。そのため、追加の特権を必要としないコードには、カーネルはありません。

Cコンパイラは、そのようなプログラムの1つの例です。カーネルモードで提供される特別な特権を必要としないため、他のほとんどのプログラムと同様に、ユーザーモードで実行されます。

Linuxの場合、カーネルは2つの部分で構成されています。カーネルのソースコードと、コンパイルされたカーネルの実行可能ファイルです。Cコンパイラを備えたすべてのマシンは、カーネルをソースコードからバイナリイメージにコンパイルできます。問題は、そのバイナリイメージをどうするかということです。

Linuxを新しいシステムにインストールすると、通常は物理メディア(CD DVDなど)またはネットワークからプリコンパイルされたバイナリイメージがインストールされます。BIOSがメディアまたはネットワークからカーネルのブートローダー(のバイナリイメージ)をロードし、ブートローダーがカーネル(のバイナリイメージ)をハードディスクにインストールします。次に、リブートすると、BIOSがカーネルからカーネルのブートローダーをハードディスクからロードし、ブートローダーがカーネルをメモリにロードします。

独自のカーネルを再コンパイルしたい場合は少しトリッキーですが、それは可能です。


5

どちらが最初にありましたか?ニワトリか卵?

卵は恐竜の時代から存在しています。

..鶏は実際には大獣の子孫であると言ってすべてを混乱させる人もいます。

カーネルを構築するにはカーネルが必要です。つまり、一方を他方で構築します。

最初のカーネルは何でもかまいません(できれ、目的の最終製品を作成できる賢明なもの^ __ ^)。

ブランのカーネル開発からのこのチュートリアル、小さめのカーネルを開発して構築し、選択した仮想マシンでテストできるようにします。

意味:カーネルをどこかで作成してコンパイルし、空の(OSではない)仮想マシンでそれを読み取ります。

これらのLinuxインストールで何が起こるかは、同じ考えに従い、さらに複雑になります。


5

カメはずっと下にありません。あなたが言うように、そのオペレーティングシステムを実行しているシステム上で、これまでコンパイルされたことがないオペレーティングシステムをコンパイルすることはできません。同様に、少なくともコンパイラーの最初のビルドは、別のコンパイラーで実行する必要があります(最初のビルドでまだ独自のソースコードをコンパイルできないことが判明した場合は、通常、後続のビルドもいくつか行います)。

最初のLinuxカーネルはMinixボックスでコンパイルされたと思いますが、それについてはよくわかりません。当時GCCが利用可能でした。多くのオペレーティングシステムの初期の目標の1つは、独自のソースコードをコンパイルするのに十分なほどコンパイラを実行することです。さらに進んで、最初のコンパイラはほぼ間違いなくアセンブリ言語で書かれていました。最初のアセンブラは、生のマシンコードで書かなければならなかった貧しい人々によって書かれました。

Linux From Scratchプロジェクトを調べてみてください。本で実際に2つのシステムを構築します。自分で構築しなかったシステム上に構築された「一時システム」と、一時システム上に構築された「LFSシステム」です。本が現在書かれている方法では、実際には別のLinuxボックスで一時システムを構築しますが、理論的には、完全に異なるOSで一時システムを構築するためにそれを適応させることができます。


1

あなたの質問を正しく理解しているなら。最近、カーネルは「自分自身をコンパイル」していません。今日のほとんどのLinuxディストリビューションは、LinuxライブCDを介したシステムインストールを提供しています。カーネルはCDからメモリにロードされ、ディスクにインストールされている場合と同じように動作します。Linux環境がシステムで稼働している場合、必要なファイルをディスクにコミットするだけで簡単です。

ブートストラップの問題について話していた場合、dmckeeはそれを非常にうまくまとめました。

別の可能性を提供するだけ...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.