rootfsとルートファイルシステム


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

rootfsとルートファイルシステムとは別物です(と理解しています)。rootfsはext2/3のようなvfs下の1つのファイルシステムで、むしろprocやsysfsの特殊ファイルシステムの1つと言った方がいいかもしれません。ファイルシステムと言えば、ストレージを持つハードディスクをイメージしますが、ユーザから見た場合、vfsのファイルシステムは、メモリー上のツリー構造(dentry)で管理したオブジェクト、と解釈した方が理解しやすいかと思います。厳密には、キャッシュ/実デバイスとのインターフェースも含んでの機能ですが。

そして、ルートファイルシステムが、ハードディスク上の実デバイス、(そしてこのデバイスは、ext2であったりext3であったりとするわけです。)と理解した方が、rootfsとルートファイルシステムの関係が見えてきます。

rootfsは、static struct file_system_type rootfs_fs_typeで定義され、システム初期化時にinit_rootfs(void)をコールする事で、register_filesystem関数でシステムのファイルシステムとして登録されます。このrootfsはスーパブロックを操作するコールバックしか定義されていません。ユーザがこのファイルシステムを操作できない。と言う事もあるかと思いますが、このファイルシステムへの読み書きが発生する場合(直接rootfsをルートファイルシステムとするようなケース)、ramfsのコールバック関数が呼ばれる事になるからです。rootfsの実態はramfsとも言える訳です。

実際、rootfsの定義は、static struct file_system_type rootfs_fs_typeだけで、inode等の他のコールバック関数は定義されていません。

get_sbであるrootfs_get_sbコールバックを見てみると、スーパブロックの取得はramfs_fill_superをコールしています。そして、sb->s_opにramfsのそれを、inode取得にramfsのそれをコールする事で実現しています。

そして、d_alloc_root()で、そのinodeに対するdentryを、/ として取得します。ある意味これ故、rootfsと言うところでしょうか。
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);
}

static int ramfs_fill_super(struct super_block * sb, void * data, int silent)
{
       struct inode * inode;
       struct dentry * root;

       sb->s_maxbytes = MAX_LFS_FILESIZE;
       sb->s_blocksize = PAGE_CACHE_SIZE;
       sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
       sb->s_magic = RAMFS_MAGIC;
       sb->s_op = &ramfs_ops;
       sb->s_time_gran = 1;
       inode = ramfs_get_inode(sb, S_IFDIR | 0755, 0);
       if (!inode)
               return -ENOMEM;

       root = d_alloc_root(inode);
       if (!root) {
               iput(inode);
               return -ENOMEM;
       }
       sb->s_root = root;
       return 0;
}

struct dentry * d_alloc_root(struct inode * root_inode)
{
       struct dentry *res = NULL;

       if (root_inode) {
               static const struct qstr name = { .name = "/", .len = 1 };

               res = d_alloc(NULL, &name);
               if (res) {
                       res->d_sb = root_inode->i_sb;
                       res->d_parent = res;
                       d_instantiate(res, root_inode);
               }
       }
       return res;
}
rootfsとはそれだけのものです。そしてルートファイルシステム(カーネルとかライブラリー等のイメージが書き込まれた実デバイス)を、rootfsの/にマウントすることで、システムが起動するわけです。

補足

ルートファイルシステムのマウントは、rootfs下に/rootを作成し、そこにルートファイルシステムをマウントした後、マウントマウントポジションを/rootが/となるように再マウントすることで実現しています。

また、rootfsはramfs上に作成される。と説明があったりいたしますが、上で見てきたように、この説明は正しくありません。rootfsとramfsはファイルシステムです。正しくはrootfsはramfsは別のものであり、ただrootfsのファイルオペレーションのコールバック関数はramfsのそれを使っている。という事実であり、rootfsの実装はramfsのそれである。と言うのが正しいところでしょうか。

最終更新 2012/01/09 18:29:16 - north
(2012/01/09 16:04:07 作成)


検索

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