Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       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 を参照)。  パラ
       メーター  valueboolinvbool パラメーターの場合は省略可能である。 配列パラメーターの
       値はカンマ区切りのリストで指定される。

   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 を無視する。

       そのモジュールがロードされるカーネルに合致することを保証するためのモジュールに組み込みの安
       全チェックがある。 これらのチェックは、 モジュールの作成時に記録され、  モジュールのロード
       時に検査される。  最初に、 モジュールはカーネルのバージョン番号と主要な機能 (CPU 種別など)
       が入った "vermagic" 文字列を記録する。 次に、 モジュールが CONFIG_MODVERSIONS 設定オプショ
       ンを有効にして作成されている場合、  バージョンハッシュがモジュールが使用するシンボルごとに
       記録される。  このハッシュはシンボルに対応する関数の引数と返り値の型を基づいて計算される。
       この場合、            シンボルのバージョンハッシュは十分に信頼できると考えられているため、
       "vermagic" 文字列内のカーネルのバージョン番号は無視される。

       MODULE_INIT_IGNORE_VERMAGIC     フラグは     "vermagic"     文字列を無視することを意味し、
       MODULE_INIT_IGNORE_MODVERSIONS  フラグはシンボルのバージョンハッシュを無視することを意味す
       る。 カーネルが強制ロードを許可するように作成されている場合 (CONFIG_MODULE_FORCE_LOAD が有
       効になっている場合)、  モジュールのロードは継続され、 そうでない場合は不正なモジュールに対
       して返るのと同じエラー ENOEXEC で失敗する。

返り値

       成功の場合、これらのシステムコールは 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 を
              参照)。

       init_module() では以下のエラーも発生する場合がある。

       EEXIST その名前のモジュールがすでにロードされている。

       EINVAL param_values が無効、 または module_image の ELF イメージの一部分に矛盾がある。

       ENOEXEC
              module_image で指定されたバイナリーイメージが ELF イメージではない、 もしくは無効な
              ELF イメージや別のアーキテクチャー用の ELF イメージである。

       finit_module() では以下のエラーも発生する場合がある。

       EBADF  fd が参照するファイルが読み出し用にオープンされていない。

       EFBIG  fd が参照するファイルが大きすぎる。

       EINVAL flags が無効である。

       ENOEXEC
              fd がオープンされたファイルを参照していない。

       上記のエラーに加え、    モジュールの    init    関数が実行されてエラーが発生した場合には、
       init_module() や finit_module() は失敗し、 errnoinit 関数が返した値が設定される。

バージョン

       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
           };

       nextrefs 以外の全てのポインター要素はモジュール本体内部を指し、 カーネル空間での適切な
       値で初期化される (つまり、モジュールの残りの 部分で再配置される) ことが期待される。

関連項目

       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/ に書かれている。