Linuxカーネルモジュールの使用の欠点を理解しようとしています。私はこれを使用すると、基本システムを再コンパイルして再起動することなく、実行中のシステムに動的にコードを挿入できるという利点を理解します。これらのパフォーマンスを考慮すると、ほとんどのカーネルコードがデフォルトのカーネルの一部ではなくカーネルモジュールに存在する必要があると思いました。しかし実際にはそうではないようです。多くのコアサブシステム(メモリ管理など)はまだカーネルに含まれています。基本カーネル。
私が考えることができる理由の1つは、カーネルモジュールが起動プロセスの非常に遅くロードされるため、コア機能がデフォルトのカーネルに入る必要があることです。私が読んだもう一つの理由は、断片化に関するものでした。
カーネルモジュールがメモリの断片化を引き起こす理由はよくわかりません。誰かが説明できますか?カーネルモジュールを使用すると、他の欠点がありますか?
答え1
はい、基本コンポーネント(mmなど)がロード可能なモジュールになることができない理由は、これらのコンポーネントが必須であるためです。カーネルがないと、カーネルは機能しません。
ロード可能モジュールに対するメモリ断片化の影響が重要であると主張する参照は見つかりませんが、この部分LLKM How-To Guideが面白いかもしれません。
私はこの問題が実際にメモリ断片化の問題の大部分だと思います。これは、通常、カーネルmmサブシステムによって管理される物理メモリの断片化と、非常に大きなアプリケーションで発生する可能性がある仮想アドレス空間の断片化という2つのレベルで発生します。私の考えでは主に設計とコンパイル方法の結果です。
実際のメモリの断片化に関しては、ページサイズ(4KB)よりも細かい単位ではこれが可能ではないと思います。したがって、実際には1024ページで100%断片化されている1MBの仮想連続空間を読む場合おそらく1,000件の追加の軽微な手術が必要です。方法ガイドのこの部分では、次の内容を読みました。
デフォルトのカーネルには、貴重な連続ドメインに再利用可能な大規模メモリ(kmallocプール)が含まれています。一部のバージョンのLinuxでは、モジュールローダーは最初にこのプールから連続メモリーを解放してLKMをロードしようとし、空き容量が不足している場合にのみvmallocスペースに移動します。 Andi Kleenは、2002年10月にLinux 2.5でこれを行うコードを提出しました。彼はその差が数パーセントの範囲にあると主張した。
ここで、vmallocスペース(ユーザースペースアプリケーションが存在する場所)はページに簡単に分割できます。これが現代のオペレーティングシステムの現実です(すべて仮想アドレス指定によってメモリを管理します)。仮想アドレッシングは、ユーザースペースで「数パーセントポイント」のパフォーマンスが低下する可能性がありますが、仮想アドレッシングに関する限り、これを介して推論することができます。必要で避けられないユーザー領域では、完全に理論的な内容にのみ関連しています。
プロセスの仮想アドレス空間(その後の物理メモリではなく)の断片化は、断片化をより複雑にする可能性がありますが、これはカーネルモジュールには適用されません(最後の段落では明らかに適用されます)。
私の意見が欲しいなら、考慮する価値はありません。高度にモジュール化されたカーネルを使用しても、最も一般的に使用されるコンポーネント(ファイルシステム、ネットワークなど)は非常に早くロードされ、ロードされた状態を維持する傾向があるため、物理メモリの連続領域にあります。それは価値があることです。 (これがしないでください)。無意味なモジュールのロードとアンロード)。
答え2
モノリシックコアを使用すると、理論的には単一の連続したメモリブロックをコアに割り当てることができる。モジュールが要求時にロード(およびアンロード)されると、すべてのカーネルメモリは連続できないため、定義に従って断片化されます。欠点は、モジュラーコアが一般にモノリシックコアよりも少ないメモリを使用することです。これは、未使用のドライバが多い可能性があるデフォルトの配布モノリシックカーネルの場合に当てはまりますが、独自のモノリシックカーネルを構築する場合は該当しません。
一部のサブシステムはモジュール化には適していません。メモリ管理は明らかに一つであり、SMPは別のものです。プロセススケジューリングはモジュラーではありませんが、I / Oスケジューリングポリシーはモジュラーです。 TCP / IPなどの複雑な相互依存性のため、他のサブシステムはモジュール化されない可能性があります。
モジュールのもう1つの問題は、起動する必要があるデバイスを駆動している場合はモジュールが悪いことです。このようなソリューションはinitrd
この問題を解決します。
最後の考慮事項はセキュリティです。カーネルロード可能ルートキットなどのロード可能モジュールを許可することは潜在的なリスクです。技巧。バラよりhttp://www.la-samhna.de/library/rootkits/index.htmlそしてhttp://www.sans.org/security-resources/malwarefaq/Ptrace.php。署名されたモジュール(カーネル3.7ベース)を強制的にロードできます。封じ込めモジュールは最後に、または他の方法で強化されました。
答え3
カーネルイメージに直接コードをコンパイルするのではなく、ロード可能なカーネルモジュールでコードをコンパイルするために他の欠点があるかどうかはわかりませんが、特定の例を使用するにはメモリ管理を想定してください。以前はカーネルバイナリイメージ自体には組み込まれず、カーネルモジュールとして組み込まれます。
- カーネルは初期RAMディスクにメモリをどのように割り当てますか?
- カーネルは、ファイルシステムをマウントするために必要な構造にメモリをどのように割り当てますか?
- カーネルは、メモリ管理モジュールをロードするためにメモリをどのように割り当てますか?
- メモリ管理モジュールは、カーネルの他の部分(メモリ管理モジュールにアクセスするために必要な他のロード可能なカーネルモジュール)がどのメモリを必要としたかをどうやって知ることができますか?
ご覧のように、これはすぐに潜在的なワーム全体を開きます。タスクスケジューリングは、別の同様のコアカーネルの概念です。
別の観点から見ると、メモリ管理モジュールなしでカーネルが何か役に立ちますか?これは、ハードウェアがシステムにインストールされていない場合に単に無効にできるハードウェアドライバとは異なります。カーネル自体を起動する必要がある基本機能です。
真のマイクロカーネルは、関心事とコード可読性/理解可能性の観点の分離による特定の利点を持っていますが、必要カーネル自体の内部の何かが動作しません。メモリとタスクの処理は、マルチタスクオペレーティングシステムカーネルの重要な概念の1つであり、上記のリストに示すように、必要なすべてのタスクのすべての意図と目的に適用されます。他に何もない場合は、別々にロードされたコンポーネントに分割しようとすると、何の利点もなく複雑さだけが追加されます(とにかく、誰もがモジュールをロードします)。
答え4
Linuxカーネルモジュールコードが使用されましたvmalloc()
。 vmalloc()
仮想メモリなので断片化の問題はありません。メモリは通常4Kbのページに分割され、仮想メモリを使用すると、断片化された物理ページを連続した仮想ブロックに再マップできます。
他の隅には、別々の仮想アドレス空間に仮想的に連続した(しかし物理的に分散した)ページを割り当てるvmalloc()があります。 vmalloc()は比較的遅いですが、カーネルと連続して見える大規模な割り当てを実行できます。たとえば、ロード可能モジュールのコードスペースを割り当てるために使用されます。