安装根文件系统式系统初始化的关键部分。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;
- }
- 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,
- };
- /** * 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);
- }
- 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;
- }
- /** * 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;
- }