ルートファイルシステム


Rev.3を表示中。最新版はこちら

カーネルが起動としてルートファイルシステムがマウントされるまでの関数の遷移は以下の通りで、ルートファイルシステムは2つのフェーズで行っている。まず内部ramディスクをルートファイルシステムとしてマウントし、その後正規のルートファイルシステムをその上にマウントし直すと言う具合だ。これはカーネルとして実ルートファイルシステムを何処からでも柔軟にマウントできるようにするための仕組みらしい。
start_kernel->vfs_caches_init->mnt_init->init_rootfs
                                       ->init_mount_tree
            ->rest_init->kernel_init->prepare_namespace->mount_root

カーネルが起動するとまず、start_kernel関数で各種オブジェクトコンポーネントの初期化を行う。その中のルートファイルシステムの処理は、VFSシステム関連の初期化を行うvfs_caches_init関数のmnt_init関数で、最初のと言うべきファイルシステムinit_rootfs関数よりルートファイルシステムをシステムに登録し、init_mount_tree関数で仮ルートファイルシステムが/としてマウントされる。

ルートファイルシステムは以下のように、スーパブロックをramfsとするramディスクである。
static struct file_system_type rootfs_fs_type = {
       .name           = "rootfs",
       .get_sb         = rootfs_get_sb,
       .kill_sb        = kill_litter_super,
};

static int rootfs_get_sb(struct file_system_type *fs_type,
       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
{
       return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super,
                           mnt);
}

その後、kernel_init関数からprepare_namespace関数で実際のルートファイルシステムがマウントされる。実際のルートファイルシステムではそのファイルシステム種類(NFSとかFDとか)により処理が分かれる。ここではHDとする。

まず、実際のルートファイルシステムを取得する。これは下記のように定義されていて、カーネルイメージの.init.setupセクションに埋め込まれたroot=から取得する。
static int __init root_dev_setup(char *line)
{
       strlcpy(saved_root_name, line, sizeof(saved_root_name));
       return 1;
}

__setup("root=", root_dev_setup);

#define __setup(str, fn)                                        \
       __setup_param(str, fn, fn, 0)

#define __setup_param(str, unique_id, fn, early)                        \
       static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \
       static struct obs_kernel_param __setup_##unique_id      \
               __used __section(.init.setup)                   \
               __attribute__((aligned((sizeof(long)))))        \
               = { __setup_str_##unique_id, fn, early }
そしてこのデバイス識別子を、MKDEVマクロでメジャー番号、マイナー番号をパックにして、静的変数ROOT_DEV(注1)に設定し、 mount_root関数で実際のルートファイルシステムをマウントする。この時ramfs下の仮ルートファイルシステムに、ROOT_DEVで/dev/rootの実ルートファイルシステムのデバイスファイルを作成し、このデバイスで仮ルートファイルシステムの/root(注2)にマウントすることになる。
       create_dev("/dev/root", ROOT_DEV);
       mount_block_root("/dev/root", root_mountflags);

そして、最後にその/rootを/にマウントポイント移動し、そこをカレントとすることで、ユーザの指定するファイルシステムをルートファイルシステムとしてマウントする。
       sys_mount(".", "/", NULL, MS_MOVE, NULL);
       sys_chroot(".");

prepare_namespace関数でルートファイルシステムをマウントすると、最終処理としてinit_post関数がよばれ、そこから、すべてのプロセスの親となるinitプロセスが起動される。initプロセスは以下順序でその1つが起動されればよい。
       run_init_process("/sbin/init");
       run_init_process("/etc/init");
       run_init_process("/bin/init");
       run_init_process("/bin/sh");

なおinitrdの場合、仮ルートファイルシステムまでは同じだが、直接initrdをramfsに読み込んで、それをマウントすることで、ROOT_DEVによるマウント処理はスキップする。(initプロセス処理も、initrd内のinitプロセス相当が起動)通常initrdはinitrd内で通常のルートファイルシステムをマウントする。

注1:
rdevコマンドはROOT_DEVを設定する。というような記述をみたことがあるが、実際は.init.setupセクションのroot=を書き換えてる。たぶん。stringコマンドで検索してみたが、カーネルイメージが圧縮してあるため確認できず。展開してっておもったけど、なんか上手くいかなかった。改めて確認。

注2:
rootのホームディレクトリのrootでない。

最終更新 2010/05/14 16:05:59 - north
(2010/05/14 15:50:32 作成)


検索

アクセス数
3690443
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。