名前
init_module, finit_module - カーネルモジュールをロードする書式
int init_module(void *module_image, unsigned long len, const char *param_values);
int finit_module(int fd, const char *param_values, int flags);注意: glibc では、 ヘッダーファイルでの init_module() の宣言はなく、 finit_module() のラッパー関数も提供されていない。 「注意」の節を参照。
説明
init_module() は ELF イメージをカーネル空間にロードし、 必要なシンボルの配置変更を行い、 モジュールパラメーターを呼び出し元から指定された値に初期化し、 最後にそのモジュールの init 関数を実行する。 このシステムコールには特権が必要である。 module_image 引数はロードするバイナリーイメージが入ったバッファーを指し、 len はバッファーのサイズを指定する。 モジュールイメージは、 実行中のカーネル用に作成された有効な ELF イメージである必要がある。 param_values 引数はモジュールパラメーター値を指定するスペース区切りの文字列である (モジュールパラメーターは module_param() や module_param_array() を使ってモジュール内で定義される)。 カーネルはこの文字列を解釈し、指定されたパラメーターを初期化する。 各パラメーター指定は以下の形式である。 name[=value[,value...]] パラメーター name はモジュール内で module_param() を使って定義されているパラメーターのいずれか一つである (Linux カーネルのソースファイル include/linux/moduleparam.h を参照)。 パラメーター value は bool か invbool パラメーターの場合は省略可能である。 配列パラメーターの値はカンマ区切りのリストで指定される。finit_module()
finit_module() システムコールは init_module() と同様だが、 ファイルディスクリプター fd からモジュールをロードする。 カーネルモジュールの信頼性をファイルシステムにおける場所から判定できる場合、この方法は有効である。 この方法が利用できる場合、 モジュールの信頼性を判定するのに暗号で署名されたモジュールを使用することによるオーバーヘッドを避ける事ができる。 param_values 引数は init_module() と同じである。 flags 引数で finit_module() の動作を変更できる。 flags は以下のフラグの 0 個以上の論理和をとって作成したビットマスクである。- MODULE_INIT_IGNORE_MODVERSIONS
- シンボルのバージョンハッシュを無視する。
- MODULE_INIT_IGNORE_VERMAGIC
- カーネルのバージョン magic を無視する。
返り値
成功の場合、これらのシステムコールは 0 を返す。エラーの場合 -1 が返され、 errno に適切な値が設定される。エラー
- EBADMSG (Linux 3.7 以降)
- モジュールの署名が正しい形式ではない。
- EBUSY
- このモジュールがシンボル参照を解決する際にタイムアウトが起こった。
- EFAULT
- アドレス引数が、プロセスがアクセスできるアドレス空間外の場所を参照していた。
- ENOKEY (Linux 3.7 以降)
- モジュールの署名が無効であるか、 カーネルがこのモジュール用の鍵を持っていない。 このエラーが返されるのは、 カーネルが CONFIG_MODULE_SIG_FORCE で作成されている場合のみである。 カーネルでこのオプションが有効になっていない場合、 無効なモジュールや署名されていないモジュールはカーネルのゴミになる。
- ENOMEM
- メモリ不足。
- EPERM
- 呼び出し元が特権 ( CAP_SYS_MODULE ケーパビリティ) を持っていなかった。もしくはモジュールのロードが無効になっている ( proc(5) の /proc/sys/kernel/modules_disabled を参照)。
- EEXIST
- その名前のモジュールがすでにロードされている。
- EINVAL
- param_values が無効、 または module_image の ELF イメージの一部分に矛盾がある。
- ENOEXEC
- module_image で指定されたバイナリーイメージが ELF イメージではない、 もしくは無効な ELF イメージや別のアーキテクチャー用の ELF イメージである。
- EBADF
- fd が参照するファイルが読み出し用にオープンされていない。
- EFBIG
- fd が参照するファイルが大きすぎる。
- EINVAL
- flags が無効である。
- ENOEXEC
- fd がオープンされたファイルを参照していない。
バージョン
finit_module() は Linux 3.8 以降で利用可能である。準拠
init_module() と finit_module() は Linux 固有である。注意
init_module() システムコールは glibc ではサポートされていない。 glibc ヘッダーでは宣言は提供されていないが、紆余曲折があり、バージョン 2.23 より前の glibc ではこのシステムコールに対する ABI を公開されていた。 そのため、 (glibc 2.23 より前では) このシステムコールを利用するには、自分のコードの中で手動でインターフェースを宣言すればよかった。 syscall(2) を使ってシステムコールを起動できる。 glibc は finit_module() に対するラッパー関数を提供していない。 syscall(2) を使って呼び出すこと。 現在ロードされているモジュールに関する情報は /proc/modules および /sys/module 以下のモジュール単位のサブディレクトリ内のファイルツリーで参照できる。 Linux カーネルのソースファイル include/linux/module.h には背景に関する有用な情報がある。Linux 2.4 以前
Linux 2.4 以前では init_module() システムコールはかなり違ったものであった。 #include <linux/module.h> int init_module(const char *name, struct module *image ); (ユーザー空間アプリケーションは query_module() を呼び出してどのバージョンの init_module() が利用可能かを検出できる。 query_module() の呼び出しは Linux 2.6 以降ではエラー ENOSYS で失敗する。) 古いバージョンのシステムコールは、 image が指す再配置されたモジュールイメージをカーネル空間にロードし、 モジュールの init 関数を実行する。 呼び出し元には再配置されたイメージを提供する責任がある (Linux 2.6 以降では init_module() システムコールが再配置自体を行う)。 モジュールイメージは先頭部分に module 構造体があり、その後ろに 適切なコードとデータが続く。 Linux 2.2 以降では module 構造体は以下のように定義されている。struct module { unsigned long size_of_struct; struct module *next; const char *name; unsigned long size; long usecount; unsigned long flags; unsigned int nsyms; unsigned int ndeps; struct module_symbol *syms; struct module_ref *deps; struct module_ref *refs; int (*init)(void); void (*cleanup)(void); const struct exception_table_entry *ex_table_start; const struct exception_table_entry *ex_table_end; #ifdef __alpha__ unsigned long gp; #endif };
next と refs 以外の全てのポインター要素はモジュール本体内部を指し、 カーネル空間での適切な値で初期化される (つまり、モジュールの残りの 部分で再配置される) ことが期待される。
関連項目
create_module(2), delete_module(2), query_module(2), lsmod(8), modprobe(8)この文書について
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。2017-09-15 | Linux |