Linuxを別のプラットフォーム要件に移植する[終了]


28

Linuxが利用可能であり、X86、ARM、PowerPCなどの多くの異なるプラットフォームに移植されていることを知っています。

しかし、移植に関しては、正確に何が必要ですか?

私の理解では、LinuxはCで書かれたソフトウェアであるということです。したがって、Linuxを元々X86からARMなどに移植する場合、特定のターゲットアーキテクチャ用のコンパイラでコードを再コンパイルするだけではありませんか?

さまざまな周辺機器用のデバイスドライバーは別として、Linuxを新しいアーキテクチャに移植する際に他に必要なことは何ですか。コンパイラは私たちのためにすべてを処理しませんか?


11
アーキテクチャ固有のカーネルソースを見たことがあると想定できますか?git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/...
Kusalananda

回答:


57

Linuxカーネルのコードの大部分はCで記述されていますが、そのコードの多くの部分は、実行中のプラットフォームに非常に固有のものであり、それを考慮する必要があります。

これの特定の例は、ほとんどのアーキテクチャ(ページテーブルの階層)で同様に機能しますが、各アーキテクチャの特定の詳細(各アーキテクチャのレベル数など)を備えた仮想メモリです。 Linuxカーネルコードは、ページテーブルのレベルが少ないアーキテクチャでコンパイラーによって省略される可能性のあるこれらの階層を走査するマクロを導入します(したがって、コードはCで記述されていますが、アーキテクチャの詳細は考慮。)

他の多くの領域は各アーキテクチャに非常に固有であり、アーチ固有のコードで処理する必要があります。ただし、これらのほとんどにはアセンブリ言語のコードが含まれます。例は次のとおりです。

  • コンテキストの切り替え:コンテキストの切り替えでは、切り替えられるプロセスのすべてのレジスタの値を保存し、CPUにスケジュールされたプロセスの保存セットからレジスタを復元します。レジスタの数とセットでさえ、各アーキテクチャに非常に固有です。通常、このコードはアセンブリに実装され、レジスタへのフルアクセスを可能にし、コンテキストスイッチングのパフォーマンスがシステムにとって重要になる可能性があるため、可能な限り高速に実行されるようにします。

  • システムコール:ユーザー空間コードがシステムコールをトリガーできるメカニズムは、通常、アーキテクチャに固有です(場合によっては特定のCPUモデルにも、たとえばIntelとAMDが異なる命令を導入したため、古いCPUにはそれらの命令がない場合があります。それらはまだユニークです。)

  • 割り込みハンドラー:割り込み(ハードウェア割り込み)の処理方法の詳細は、通常プラットフォーム固有であり、通常、プラットフォームで使用されている特定の呼び出し規則を処理するためのアセンブリレベルの接着剤が必要です。また、割り込みを有効/無効にするためのプリミティブは通常プラットフォーム固有であり、アセンブリコードも必要です。

  • 初期化初期化の方法の詳細には、通常、プラットフォームに固有の詳細も含まれ、多くの場合、カーネルへのエントリポイントを処理するためにいくつかのアセンブリコードが必要です。複数のCPU(SMP)を備えたプラットフォームでは、通常、他のCPUをオンラインにする方法の詳細もプラットフォーム固有です。

  • ロックプリミティブ:いくつかのアーキテクチャでは、それらを効率的に実装するために異なるCPU命令を提供する(または好む)ため、ロックプリミティブ(スピンロックなど)の実装には、通常プラットフォーム固有の詳細も含まれます。アトミック操作を実装するものもあれば、アトミックにテスト/更新できるcmpxchgを提供するものもあります(ただし、他のライターが最初に侵入した場合は失敗します)。多くの場合、これらにはアセンブリコードの記述も含まれます。

プラットフォームまたはアーキテクチャ固有のコードがカーネルで必要とされ、おそらく他の領域(具体的には、またはLinuxカーネルでは、。)があり、カーネルのソースツリーを見ると、下のアーキテクチャ固有のサブツリーがあるarch/と下のinclude/arch/あなたはもっと見つけることができますが、この例。

実際には驚くべきものもあります。たとえば、各アーキテクチャで使用できるシステムコールの数は異なり、一部のアーキテクチャでは一部のシステムコールが存在し、他のアーキテクチャでは存在しないことがわかります。(x86でも、システムコールのリストは32ビットカーネルと64ビットカーネルで異なります。)

要するに、プラットフォーム固有のカーネルが認識する必要のあるケースはたくさんあります。Linuxカーネルはそれらのほとんどを抽象化しようとするため、高レベルのアルゴリズム(メモリ管理やスケジューリングの仕組みなど)をCで実装し、すべてのアーキテクチャで同じ(またはほぼ同じ)動作をさせることができます。


7
とてもいい記事です!syscallの数の変動は、主に履歴に関連しています。新しいポートには、ポートの時点で有効なsyscallが含まれます。古いポートに存在する歴史的な荷物に煩わされないため、非推奨のsyscallは通常ポートに存在しません非推奨よりも新しい。(すべてのシナリオをカバーしているわけではありません...)
スティーブン・キット

10

Linuxカーネルの移植に加えて、「ユーザー空間」プログラム用のアプリケーションバイナリインターフェイス(ABI)を定義し、ユーザー空間ソフトウェアスタックの最下層を移植する必要があります。Linuxは通常、GNUプロジェクトの低レベルのユーザースペースコンポーネントで使用されます。最も重要なコンポーネントは次のとおりです。

  • Cコンパイラー、アセンブラー、およびリンカー:GCCおよびGNU Binutils。まったく新しいCPUアーキテクチャの場合、カーネル自体はCプログラムであり、コンパイルする必要があるため、カーネルの移植を開始する前に、このソフトウェアを移植する必要があります。OSカーネルとしてLinuxだけではなく、プラットフォームのCPUに対して既に「バックエンド」サポートがある場合、実行する作業が大幅に少なくなり、カーネルが起動してランニング。
  • Cランタイムライブラリ:「GNU libc」。このライブラリには、システムコールを行うコードや、カーネルと直接やり取りするコードが含まれています。
  • 「外部関数インターフェース」ライブラリlibffiは、多くの高レベル言語インタープリターの必須コンポーネントであり、少量の手書きアセンブリ言語を必要とする数少ない残りのタスクの1つを実行します。

他の多くのソフトウェアには、オプションのプラットフォーム依存コンポーネントがあります。たとえば、新しいCPUアーキテクチャ用にNSSOpenSSL用に手動で最適化された暗号プリミティブ、およびIonMonkeyV8用にジャストインタイムコンパイルバックエンドを記述すると、Webブラウジングが大幅に高速になります。しかし、これらは新しいプラットフォームを立ち上げるために不可欠ではありません。


1

移植するハードウェアについてカーネルに伝える必要があります。カーネルの仕事はハードウェアと直接インターフェースすることです。そのため、カーネルは適切に機能するために、CPU、オシレーター(クロック)、およびさまざまな種類のシリアルポート(SPI、CAN、 I2Cなど)。

昔は、ドライバーが機能するために使用するプラットフォーム固有のコードを書くことでこれを行いました。最近では、これはデバイスツリー定義を記述することで行われます

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