安裝根文件系統式系統初始化的關鍵部分。Linux內核允許根文件系統放在很多不同的地方,比如硬盤分區、軟盤、通過NFS共享的遠程文件系統以及保存在ramdisk中。內核要在變量ROOT_DEV中尋找包含根文件系統的磁盤主設備號。當編譯內核時,或者像最初的啟動裝入程序傳遞一個合適的“root”選項時,根文件系統可以被指定為/dev目錄下的一個設備文件。
相關閱讀:
http://www.linuxidc.com/Linux/2012-02/53771.htm
安裝根文件系統分為兩個階段:
1,內核安裝特殊rootfs文件系統,該文件系統僅提供一個作為初始安裝點的空目錄
start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()
[cpp]
- /*初始化根文件系統*/
- int __init init_rootfs(void)
- {
- int err;
- /*初始化ramfs_backing_dev_info*/
- err = bdi_init(&ramfs_backing_dev_info);
- if (err)
- return err;
- /*注冊rootfs_fs_type文件類型*/
- err = register_filesystem(&rootfs_fs_type);
- if (err)/*如果出錯,銷毀上面初始化的*/
- bdi_destroy(&ramfs_backing_dev_info);
-
- return err;
- }
[cpp]
- static struct backing_dev_info ramfs_backing_dev_info = {
- .name = "ramfs",
- .ra_pages = 0, /* No readahead */
- .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK |
- BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |
- BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,
- };
[cpp]
- /**
- * register_filesystem - register a new filesystem
- * @fs: the file system structure
- *
- * Adds the file system passed to the list of file systems the kernel
- * is aware of for mount and other syscalls. Returns 0 on success,
- * or a negative errno code on an error.
- *
- * The &struct file_system_type that is passed is linked into the kernel
- * structures and must not be freed until the file system has been
- * unregistered.
- */
- /*注冊一個新的文件系統*/
- int register_filesystem(struct file_system_type * fs)
- {
- int res = 0;
- struct file_system_type ** p;
-
- BUG_ON(strchr(fs->name, '.'));
- if (fs->next)
- return -EBUSY;
- INIT_LIST_HEAD(&fs->fs_supers);
- write_lock(&file_systems_lock);
- /*從system_type鏈表中查找指定名稱的file_system_type*/
- p = find_filesystem(fs->name, strlen(fs->name));
- if (*p)
- res = -EBUSY;
- else
- *p = fs;
- write_unlock(&file_systems_lock);
- return res;
- }
根文件系統定義如下
[cpp]
- static struct file_system_type rootfs_fs_type = {
- .name = "rootfs",
- .get_sb = rootfs_get_sb,
- .kill_sb = kill_litter_super,
- };
下面看看他的兩個函數
[cpp]
- /*獲得根目錄的sb*/
- 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);
- }
[cpp]
- int get_sb_nodev(struct file_system_type *fs_type,
- int flags, void *data,
- int (*fill_super)(struct super_block *, void *, int),
- struct vfsmount *mnt)
- {
- int error;
- /*獲得sb結構*/
- struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
-
- if (IS_ERR(s))
- return PTR_ERR(s);
-
- s->s_flags = flags;
- /*這裡實際調用ramfs_fill_super,對sb結構的屬性進行設置*/
- error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
- if (error) {
- deactivate_locked_super(s);
- return error;
- }
- s->s_flags |= MS_ACTIVE;
- simple_set_mnt(mnt, s);/*設置mnt和sb關聯*/
- return 0;
- }
[cpp]
- /**
- * sget - find or create a superblock
- * @type: filesystem type superblock should belong to
- * @test: comparison callback
- * @set: setup callback
- * @data: argument to each of them
- */
- /*查找或創建一個sb結構*/
- struct super_block *sget(struct file_system_type *type,
- int (*test)(struct super_block *,void *),
- int (*set)(struct super_block *,void *),
- void *data)
- {
- struct super_block *s = NULL;
- struct super_block *old;
- int err;
-
- retry:
- spin_lock(&sb_lock);
- if (test) {
- list_for_each_entry(old, &type->fs_supers, s_instances) {
- if (!test(old, data))
- continue;
- if (!grab_super(old))
- goto retry;
- if (s) {
- up_write(&s->s_umount);
- destroy_super(s);
- }
- return old;
- }
- }
- if (!s) {/*如果找不到sb,從內存中申請一個*/
- spin_unlock(&sb_lock);
- s = alloc_super(type);
- if (!s)
- return ERR_PTR(-ENOMEM);
- goto retry;
- }
-
- err = set(s, data);
- if (err) {
- spin_unlock(&sb_lock);
- up_write(&s->s_umount);
- destroy_super(s);
- return ERR_PTR(err);
- }
- /*初始化得到的sb結構*/
- s->s_type = type;
- strlcpy(s->s_id, type->name, sizeof(s->s_id));
- /*加入鏈表尾*/
- list_add_tail(&s->s_list, &super_blocks);
- list_add(&s->s_instances, &type->fs_supers);
- spin_unlock(&sb_lock);
- get_filesystem(type);
- return s;
- }