なんらかの理由で、Linux のユーザー空間からカーネル空間にコードを移動したいという人もいます。多くの場合、その理由は、コードの優先度を特に高くする必要があるか、単に「カーネル空間の方が速い」ためです。
これは私には奇妙に思えます。いつカーネル モジュールの作成を検討する必要がありますか? 一連の基準はありますか?
そこに属する(私が信じている)ユーザー空間にコードを保持するように動機付けるにはどうすればよいですか?
経験則:コードをユーザー空間に保持するために最善を尽くしてください。できないと思う場合は、コードを書くのと同じくらい多くの時間をカーネル コードの代替案の調査に費やしてから (つまり、長い時間)、ユーザー空間での実装を再試行してください。それでもできない場合は、さらに調査して正しい選択を行っていることを確認してから、非常に慎重にカーネルに移行してください。他の人が言っているように、カーネル モジュールの作成とカーネル コードのデバッグが非常に地獄になるような状況はほとんどないため、何としても避けてください。
カーネル モード コードの記述を検討する際に確認する必要がある具体的な条件については、次のとおりです。 割り込みなど、非常に低レベルのリソースにアクセスする必要があるか。あなたのコードは、現在エクスポートされている機能の上に構築できないハードウェア用の新しいインターフェイス/ドライバーを定義していますか? コードは、カーネル空間からエクスポートされていないデータ構造またはプリミティブにアクセスする必要がありますか? スケジューラーや VM システムなど、他のカーネル サブシステムで主に使用されるものを作成していますか (ここでも、サブシステムがカーネル モードである必要はありません。Mach は、ユーザー モードの仮想メモリ ページャーを強力にサポートしています。だからそれは間違いなく行うことができます)?
カーネルに何かを入れる理由は非常に限られています。デバイス ドライバを作成している場合は問題ありません。標準的なアプリケーション: ありません。
欠点は非常に大きいです。デバッグが難しくなり、エラーがより頻繁に発生し、見つけにくくなります。セキュリティと安定性が損なわれる可能性があります。カーネルの変更により頻繁に適応する必要がある場合があります。他の UNIX OS への移植ができなくなります。
私がカーネルに最も近いものはカスタム ファイルシステム (バックグラウンドで mysql を使用) であり、そのためにも FUSE を使用しました (U はユーザー空間を表します)。
質問が正しいかどうかはわかりません。物事をカーネル空間に移動する正当な理由があるはずです。理由がなければやらない。
1 つには、デバッグが難しくなり、バグの影響がはるかに悪化します (単純なコアダンプではなく、クラッシュ/パニック)。
基本的にはrpjに賛成です。本当に必要でない限り、コードはユーザー空間になければなりません。
しかし、あなたの質問を強調するために、どの状態ですか?
ドライバーはカーネル内にある必要があると主張する人もいますが、これは正しくありません。一部のドライバーはタイミングに敏感ではありません。実際、多くのドライバーはそのようなものです。
たとえば、フレーマー、RTC タイマー、i2c デバイスなどです。これらのドライバーは、ユーザー空間に簡単に移動できます。ユーザー空間に書き込まれるファイルシステムもあります。
オーバーヘッドがあるカーネル空間に移動する必要があります。ユーザーカーネルスワップは、コードが正しく機能するために受け入れられなくなります。
しかし、これに対処する方法はたくさんあります。たとえば、/dev/mem は、カーネル空間から行うのと同じように、物理メモリにアクセスするための優れた方法を提供します。
RTOS への移行について人々が話すとき、私はたいてい懐疑的です。最近では、プロセッサが非常に強力であるため、ほとんどの場合、リアルタイムの側面は無視できます。
しかし、たとえば、SONET を扱っていて、50 ミリ秒以内に保護切り替えを行う必要がある場合でも (50 ミリ秒の制約がリング全体に適用されるため、実際にはさらに短くなります)、切り替えを非常に高速に行うことができます。ハードウェアがサポートします。
最近の多くのフレーマーは、必要な書き込みの量を減らすハードウェア サポートを提供できます。あなたの仕事は基本的にできるだけ早く割り込みに応答します。そして、Linux はまったく悪くありません。他の多くの割り込み (IDE、イーサネットなど) を実行している場合でも、割り込みレイテンシは 1 ミリ秒未満でした。
それでも十分でない場合は、ハードウェアの設計が間違っている可能性があります。ハードウェアに残したほうがよいものもあります。ハードウェアとは、ASIC、FPGA、ネットワーク プロセッサ、またはその他の高度なロジックを意味します。
カーネルで実行されるコードは、ユーザー空間コードとは異なる方法でメモリ、周辺機器、システム機能にアクセスするため、より効率的になることができます。カーネル コードのセキュリティ制限が緩和されたことは言うまでもありません。ただし、これには通常、カーネルがセキュリティの脅威にさらされる可能性が高くなったり、OS がロックされたり、デバッグが複雑になったりするなどの代償が伴います。
人々が本当に高い優先度、決定論、低遅延などを望んでいる場合、正しい方法はLinux(または他のOS)のリアルタイムバージョンを使用することです。
プリエンプティブカーネルオプションなども確認してください。正確に何をすべきかは要件によって異なりますが、一部のハードウェアを直接インターフェースしない限り、コードをカーネルモジュールに配置することは適切な解決策ではない可能性があります。
コードをカーネル空間に移動しないもう 1 つの理由は、それを実稼働または商用の状況で使用する場合、GPL 契約によりそのコードを公開する必要があるためです。多くのソフトウェア企業が入りたくない状況です。:)
原則として。知りたいことを考えてみてください。それがオペレーティング システムの開発に関する本やクラスで見られるものであれば、カーネルに属する可能性が高いでしょう。そうでない場合は、カーネルから除外してください。そのルールを破る非常に正当な理由がある場合は、自分でそれを知るのに十分な知識を持っているか、その知識を持っている人と一緒に働いていることを確認してください.
はい、耳障りに聞こえるかもしれませんが、これはまさに私が言いたかったことです。わからない場合は、答えが「いいえ」であることをほぼ確信してください。カーネルでは実行しないでください。開発をカーネル空間に移すと、確実に処理できなければならないワームの巨大な缶が開かれます。
レイテンシーの短縮、スループットの向上などが必要な場合は、カーネル コードを開発するよりも高速なコンピューターを購入する方がおそらく安価です。
カーネル モジュールは(コンテキスト スイッチが少なく、システム コールのオーバーヘッドが少なく、割り込みが少ないため) 高速である可能性があり、確かに非常に高い優先度で実行されます。少量の非常に単純なコードをカーネル空間にエクスポートしたい場合は、これで問題ないかもしれません。つまり、小さなコードがパフォーマンスにとって重要であることが判明し、カーネル モードに配置することでメリットが得られる種類のコードである場合、そこに配置することが正当化される可能性があります。
ただし、他のすべてのオプションが完全に使い果たされない限り、プログラムの大部分をカーネル空間に移動することは避けるべきです。そうすることの難しさは別として、パフォーマンス上の利点はそれほど大きくない可能性があります。