5

Linuxでは、デバイスドライバーがロード可能なカーネルモジュールとして構築されている場合、デバイスドライバーカーネルモジュールを挿入すると、カーネルはmodule_init()マクロで示されるようにデバイスドライバーのinit関数を呼び出します。

これは、カーネルに静的にコンパイルされたデバイスドライバーに対してどのように機能しますか?それらのinit関数はどのように呼ばれますか?

4

2 に答える 2

6

組み込みドライバーのinitmodule_init()ルーチンは、引き続きマクロを使用してそのエントリポイントを宣言できます。または、ドライバーがdevice_initcall()ロード可能なモジュールとしてコンパイルされない場合に、ドライバーを使用できます。または、起動シーケンスの非常に早い段階で初期化を移動するために、ドライバーはを使用できますsubsys_initcall()

これらのinitルーチンinclude/linux/init.hを呼び出すシーケンスでは、次のように記述されます。

/* initcalls are now grouped by functionality into separate 
 * subsections. Ordering inside the subsections is determined
 * by link order. 
 * For backwards compatibility, initcall() puts the call in 
 * the device init subsection.
 *
 * The `id' arg to __define_initcall() is needed so that multiple initcalls
 * can point at the same handler without causing duplicate-symbol build errors.
 */

デバイスドライバーのこれらのサブセクションdriversは、Linuxカーネルソースツリーのディレクトリ内のサブディレクトリに対応し、リンクの順序はの各サブディレクトリのbuilt-in.oファイルに記録されていると思いますdrivers。したがって、カーネルの起動中に、各組み込みドライバのinitルーチンは最終的にinによって実行さdo_initcalls()init/main.cます。

デバイスドライバのinitルーチンは、HWデバイスが実際に存在することを確認するためにシステムをプローブする役割を果たします。プローブに障害が発生した場合、ドライバーはリソースを割り当てたり、デバイスを登録したりしないでください。

更新
カーネルコマンドラインでオプション「initcall_debug」を渡すと、各initcallのタイミング情報がコンソールに出力されます。initcallsは、静的にリンクされたカーネルドライバーとサブシステムを初期化し、Linuxのブートプロセスにかなりの時間を費やすために使用されます。出力は次のようになります。

calling  tty_class_init+0x0/0x44 @ 1
initcall tty_class_init+0x0/0x44 returned 0 after 9765 usecs
calling  spi_init+0x0/0x90 @ 1
initcall spi_init+0x0/0x90 returned 0 after 9765 usecs

参照:http ://elinux.org/Initcall_Debug

于 2012-10-13T01:36:50.593 に答える
2

kernelinit.hのコメントで指定されているとおり

「module_init()は、do_initcalls()(組み込みの場合)またはモジュール挿入時(モジュールの場合)のいずれかで呼び出されます。」

init.hを調べると、次のように表示されます。

module_init(x)__initcall(x);を定義します。

そして、あなたが注意深く観察するならば、

__initcall(fn)を定義しますdevice_initcall(fn)

device_initcall(fn)を定義します__define_initcall( "6"、fn、6)

したがって、基本的にモジュールinitは、起動時にのみinitcall(注:静的にコンパイルされたモジュールの場合のみ)につながります。

于 2012-10-20T12:14:25.413 に答える