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