3

サンプルの hello.ko カーネル モジュールを作成しました。

#include <linux/module.h>      /* Needed by all modules */
#include <linux/kernel.h>      /* Needed for KERN_INFO */

int init_module(void)
{
        printk(KERN_INFO "Hello world.\n");
        return 0;
}

void cleanup_module(void)
{
        printk(KERN_INFO "Goodbye world 1.\n");
}

ここでは、Linux が公開しているカーネル API である「printk」メソッドを使用しました。「/proc/kallsyms」に Linux でエクスポートされたシンボルが表示されます。gcc/ld が呼び出されたカーネル API をどのようにリンクするのか知りたいです。gcc/ld は「/proc/kallsyms」などのファイルからカーネル メソッドのアドレスを取得し、リンクを実行しますか? はいの場合、gcc/ld はどのようにしてそれを知ることができますか? それを伝えるオプションはありませんでした。

4

1 に答える 1

8

Linux カーネルのモジュール ローダーには、基本的に専用の実行時リンカーが含まれています。.ko ファイルは実際には他のファイルと同様にオブジェクト ファイルであり、シンボル テーブルが付属しています。これを実行nmすると ( nm <path/to/some_module.ko>)、「U」、つまり「未定義」とマークされた記号が多数表示されます。printkこれには、__kmalloc、 、など、モジュールによって使用されるコア カーネル関数のシンボルが含まれますkfreeが、多くの場合、他のモジュールによって実装されるシンボルも含まれます。

モジュールがロードされると、カーネルはモジュールの未定義シンボルを実行し、(実行時) シンボル テーブルでそれらを検索し、他のリンカーと同様に、関連するメモリ ロケーションにパッチを適用します。未定義のシンボルがまだシンボル テーブルにない場合、読み込みは失敗します (依存関係を読み込まないため、insmod代わりに使用することで簡単にデモできます)。modprobeまた、モジュールによってエクスポートされたシンボルを、他のモジュールが使用できるようにシンボル テーブルに追加し、依存関係を追跡して、別のモジュールが使用するモジュールをヤンクアウトできないようにします。Ilya Matveychikovは、コメント内のモジュール ローダーの関連コードにリンクしています。これは、すべての詳細を知りたい場合に役立ちます。

于 2012-06-12T16:55:02.723 に答える