Linux カーネルのコードの大部分は C で記述されていますが、そのコードには、それが実行されているプラットフォームに非常に固有であり、それを考慮する必要がある部分がまだ多くあります。
この特定の例の 1 つは仮想メモリです。仮想メモリは、ほとんどのアーキテクチャ (ページ テーブルの階層) で同様の方法で機能しますが、アーキテクチャごとに特定の詳細 (各アーキテクチャのレベル数など) があり、これは x86 でも増加しています。新しいより大きなチップの導入。) Linux カーネル コードは、ページ テーブルのレベルが少ないアーキテクチャのコンパイラによって省略される可能性のあるこれらの階層のトラバースを処理するマクロを導入します (そのため、コードは C で記述されますが、アーキテクチャの詳細は)
他の多くの領域は各アーキテクチャに非常に固有であり、アーキテクチャ固有のコードで処理する必要があります。ただし、これらのほとんどにはアセンブリ言語のコードが含まれます。例:
-
コンテキストの切り替え :コンテキストの切り替えには、切り替えられるプロセスのすべてのレジスタの値を保存し、CPU にスケジュールされたプロセスの保存されたセットからレジスタを復元することが含まれます。レジスタの数とセットでさえ、各アーキテクチャに非常に固有です。コンテキスト切り替えのパフォーマンスはシステムにとって重要な場合があるため、このコードは通常、アセンブリで実装され、レジスタへの完全なアクセスを許可し、可能な限り高速に実行されるようにします。
-
システム コール :ユーザー空間コードがシステム コールをトリガーできるメカニズムは、通常、アーキテクチャに固有です (また、特定の CPU モデルにさえ、たとえば、Intel と AMD がそのための異なる命令を導入したこともあり、古い CPU にはそれらの命令がない可能性があるため、それらの詳細一意のままです。)
-
割り込みハンドラ :割り込み (ハードウェア割り込み) の処理方法の詳細は、通常、プラットフォーム固有であり、通常、プラットフォームで使用されている特定の呼び出し規約を処理するために、アセンブリ レベルの接着剤が必要です。また、割り込みを有効/無効にするためのプリミティブは通常、プラットフォーム固有であり、アセンブリ コードも必要です。
-
初期化 :初期化がどのように行われるかの詳細には、通常、プラットフォームに固有の詳細も含まれており、多くの場合、カーネルへのエントリ ポイントを処理するためのアセンブリ コードが必要です。複数の CPU (SMP) を備えたプラットフォームでは、通常、他の CPU をオンラインにする方法の詳細もプラットフォーム固有です。
-
プリミティブのロック :ロック プリミティブ (スピンロックなど) の実装には、通常、プラットフォーム固有の詳細も含まれます。これは、アーキテクチャによっては、それらを効率的に実装するために異なる CPU 命令を提供 (または優先) するためです。アトミック操作を実装するものもあれば、アトミックにテスト/更新できる cmpxchg を提供するものもあれば (ただし、別のライターが最初にアクセスすると失敗する)、CPU 命令に「ロック」修飾子を含めるものもあります。これらには、多くの場合、アセンブリ コードの記述も含まれます。
おそらく、プラットフォームまたはアーキテクチャ固有のコードがカーネル (具体的には Linux カーネル) に必要な領域が他にもあるでしょう。カーネル ソース ツリーを見ると、03 12以下
たとえば、各アーキテクチャで利用可能なシステム コールの数が異なり、一部のシステム コールは一部のアーキテクチャに存在し、他のアーキテクチャには存在しないことがわかります。 (x86 でも、syscall のリストは 32 ビット カーネルと 64 ビット カーネルで異なります。)
要するに、カーネルが認識しなければならないプラットフォーム固有のケースはたくさんあります。 Linux カーネルはそれらのほとんどを抽象化しようとするため、高レベルのアルゴリズム (メモリ管理やスケジューリングの仕組みなど) を C で実装し、すべてのアーキテクチャで同じ (またはほぼ同じ) に動作させることができます。
Linux カーネルの移植に加えて、アプリケーション バイナリ インターフェイスを定義する必要があります。 (ABI)「ユーザー空間」プログラム用であり、ユーザー空間ソフトウェアスタックの最下層を移植します。 Linux は通常、GNU プロジェクトの低レベルのユーザー空間コンポーネントと共に使用されます。最も重要なものは次のとおりです:
- C コンパイラ、アセンブラ、リンカ:GCC と GNU Binutils。まったく新しい CPU アーキテクチャの場合、カーネル自体が C プログラムであり、コンパイルする必要があるため、カーネルの移植を開始する前に、このソフトウェアを移植する必要があります。プラットフォームの CPU の「バックエンド」サポートが既にあり、Linux を OS カーネルとして使用していない場合は、実行する作業が大幅に少なくなり、カーネルが起動して大部分の作業を延期することで回避できる可能性があります。
- C ランタイム ライブラリ:「GNU libc」。このライブラリには make するコードが含まれています システム コールを実行したり、カーネルと直接やり取りしたりします。
- 「外部関数インターフェイス」ライブラリ libffi は、多くの高水準言語インタープリターの必須コンポーネントであり、必要な数少ない残りのタスクの 1 つを実行します。 少量の手書きのアセンブリ言語
他の多くのソフトウェアには、プラットフォームに依存するオプションのコンポーネントがあります。たとえば、新しい CPU アーキテクチャ用の NSS と OpenSSL 用に手動で最適化された暗号化プリミティブを記述し、IonMonkey と V8 用のジャストインタイム コンパイル バックエンドを作成すると、Web ブラウジングが大幅に高速化されます。しかし、これらは新しいプラットフォームを立ち上げるのに不可欠ではありません.