initプロセスの起動

即/etc/initが動作を始める訳ではなく、最初は下記関数を実行するカーネルスレッドとして実行を開始する。initはファイルシステム上のinitコマンドを実行する前に、カーネル初期化処理の続き(do_basic_setup関数)を行う。 これら処理をstart_kernel関数でなく、こちらで行う理由は、start_kernel関数と異なり待ちに入ることが出来るためだと思われる。

    init()
        カーネル初期化処理を行う(do_basic_setup関数)
        標準入出力用にコンソール(/dev/console)をオープン

        if(BOOTからの要求があれば)
            BOOTから指定されたコマンドをexecする
        initコマンドをexecする
        if(initコマンドのexecに失敗したら)
            シェル(/bin/sh)をexecする

    do_basic_setup()
        (各種初期化)
            :
            :
        各種バスの初期化(PCIバス、USBバスなど)

        ネットワークデータ初期化(sock_init関数)
        各種初期化関数呼び出し(do_initcalls関数)。
             (各種ドライバの初期化関数もここで呼び出される)
        各種ファイルシステムの登録(filesystem_setup関数)
        rootファイルシステムのマウント(mount_root関数)
        devfs(inodeとdentryだけけの実態の無いfs)のマウント(mount_devfs_fs関数)

        if(ラムディスクがrootの場合) {
                スレッドを生成 "/linuxrc" コマンドを実行する。
        }

各種初期化関数をdo_initcalls関数で呼び出されるようにするには、以下のようにする必要がある。例えば、システム起動時にinit_foo()という関数が呼び出されるようにするには、その機能の中で以下のように宣言する。自動的にinitcall_startテーブルに登録され、システム起動時にdo_initcalls関数から呼び出される。

   init_foo() {
         foo機能の初期化;
   }
   __initcall(init_foo);

ただしモジュールとしてコンパイルできるものは, initcall(init_foo) の代わりに, module_init(init_foo) と宣言する.

Linuxカーネルへのスタティックリンクとしてコンパイルする時には, initcall(init_foo)と置き換えられる.

モジュールとしてコンパイルする時には, init_module()関数に置き換えられ, モジュールのロード時に初期化関数として呼び出される.


(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST
1