2

最近、古いプロジェクトの1つを選び、ほとんどゼロから再開しました。私はしばらく病気だったので、一生懸命取り締まり、たくさんの機能を実装する時間がありました。ただし、実装するのが良いと思うことの1つは、モジュールのロードです。モジュールのカーネルモードの動的ローディングを実行したい。

モジュールという言葉は少し曖昧です。正しい用語は、カーネルモードドライバ用のCライブラリのミニチュア実装や、 IRQ 0および1にあるPITキーボードなどの標準的なものなど、ライブラリをロードすることです。私が達成しようとしている方法は、少し自立しています。私のカーネルがロードするモジュールの側面では、ユーザーモードに入るためにカーネル自体で使用されます。

例として、私のカーネルは、自分で実装したCライブラリの関数をほとんど使用していません。これらの関数自体は、GDT、IDT、IRQ、ISRなどのセットアップで使用されます。これらの関数を、カーネルがロードして使用できるライブラリに抽象化したいと思います。つまり、カーネル自体は、何かをセットアップする前に、最初の段階でモジュールをロードする必要があります。

ここで、これを自分で行ういくつかの方法を考えました。たとえば、ライブラリ自体の関数のアドレスが割り当てられた関数ポインターのテーブルを使用して、このライブラリに構造を追加するなどです。ライブラリをout-kludgeファイルとしてコンパイルし、ライブラリをvoid *としてカーネルにロードし(アロケータが機能しているので問題ありません)、構造のオフセットを計算し、voidポインタにその分ステップインします。カーネルで構造を再作成します。関数ポインタのテーブルを割り当てる必要があるため、これは機能するようには聞こえません。つまり、ライブラリ自体に初期化関数が必要です。住所を知っていたとしても、それはどのように呼ばれるのでしょうか?

そのようなローダーをどのように実装できるかについてはわかりませんが、それだけの価値はありますか?可能な限り抽象化したいのですが、私のカーネルはモジュラー設計になっています。また、このメソッドを使用してドライバーやその他のものをロードすることも期待していますが、どのように実装するかはわかりません。私はすでにさまざまな方法を試しましたが、すべて失敗しました。私は何をすべきか?

4

2 に答える 2

2

最初に動的ローダーをユーザー空間に作成することをお勧めします。必要な手法は非常に似ており、後でコードの大部分をカーネル空間に適応させることができます。また、 a.out を使用したり、独自の「関数ポインターのテーブル」を作成したりしないでください。 ELFなどのより最新の形式を使用してください。コンパイル時のツールは既に存在するため、これにより多くの労力を節約できます。適切なリンカー スクリプトを記述し、Linux GCC から直接ビルドするだけです。

たまたま、Windows カーネルはあなたの言うことと非常によく似た動作をします。Windows カーネル (ntoskrnl.exe) は、さまざまな DLL (PSHED.dll、HAL.dll、KDCOM.dll、CLFS. sys、および私のシステムの Cl.dll)。この場合、NTLDR プログラムは ntoskrnl.exe が必要とするすべてのファイルをメモリにロードし、ntoskrnl.exe のブート スタブが動的リンクを実行します。後で、同じ動的リンカーを使用して、他のドライバーもロードできます。

于 2011-06-30T23:44:29.617 に答える