組み込みドライバーのロード順序をカスタマイズするにはどうすればよいですか (いくつかの組み込みドライバー モジュールを最初にロードし、依存モジュールを後でロードするようにします)。
4 に答える
組み込みドライバーはロードされないため、組み込みです。それらの初期化関数が呼び出され、カーネルがそれ自体をセットアップするときにドライバーがアクティブ化されます。これらの init 関数は で呼び出されinit/main.c::do_initcalls()
ます。すべての init 呼び出しは、initcall_levels
およびで定義されるレベルに分類されます。include/linux/init.h
これらのレベルは、リンカー スクリプト ( arch/*/kernel/vmlinux.lds.*
) で定義された実際のシンボルです。カーネルのコンパイル時に、リンカーはmodule_init()
or otherとマークされたすべての関数を収集*_initcall()
し、レベルで分類し、同じレベルのすべての関数を同じ場所にまとめて、関数ポインターの配列のように作成します。
実行時に do_initcall_level() が行うことは、配列内のポインターが指す各関数を呼び出すことです。do_initcall_level にはレベル以外の呼び出しポリシーはありませんが、配列内の順序はリンク時に決定されます。
これで、ドライバーの開始順序がリンク時に固定されていることがわかりましたが、何ができるでしょうか?
- init 関数をより高いレベルに配置するか、または
- デバイスドライバーをより高い位置に置きます
Makefile
上記を読めば、最初のものは明らかです。つまり、適切であれば、代わりに Early_initcall() を使用してください。
2 つ目は、もう少し説明が必要です。問題の順序が異なる理由はMakefile
、現在のカーネル ビルド システムがどのように機能し、リンカーがどのように機能するかです。簡単に言うと、ビルド システムはすべてのオブジェクト ファイルを取り込み、obj-y
それらをリンクします。obj-y
これは環境に大きく依存しますが、リンカが最初のオブジェクト ファイルを下位アドレスに配置する可能性が高いため、以前に呼び出されます。
ドライバーを同じディレクトリ内の他のドライバーよりも早く呼び出したい場合は、これが最も簡単な方法です。
depmod
エクスポートされ、各モジュールに必要なシンボルを調べ、modprobe
後でモジュールを適切な順序でロードするために使用できるトポロジカルソートを行います。依存したいモジュールからシンボルを要求するだけで、正しいことを行うことができます。