根文件系统挂载流程

1、普通的根文件系统存放在flash中的某个分区

根文件系统挂载流程_第1张图片

 

因此需要告知内核根文件系统存放在哪个分区中,同时需要知道根文件系统的rootfstype类型。见

mount挂载分析_sydyh43的博客-CSDN博客

2、设备启动阶段,在内核加载最后阶段,需要挂载根文件系统,然后访问根文件系统中的第一个用户进程init

3、挂载函数流程

    //init/main.c
    start_kernel
        rest_init
            kernel_init                //kernel_thread(kernel_init, NULL, CLONE_FS);
                kernel_init_freeable
                    prepare_namespace

prepare_namespace函数中实现挂载前的准备,解析第1点介绍的分区和rootfstype内容

 

   void __init prepare_namespace(void)
    {
        ......
        if (saved_root_name[0]) {
            root_device_name = saved_root_name;
            if (!strncmp(root_device_name, "mtd", 3) ||
                !strncmp(root_device_name, "ubi", 3)) {
                mount_block_root(root_device_name, root_mountflags);
                goto out;
            }
            ROOT_DEV = name_to_dev_t(root_device_name);        //这步很关键,解析/dev/mtdblock2的主次设备号,存入ROOT_DEV。可以printk("device %u:%u.\n", MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
            if (strncmp(root_device_name, "/dev/", 5) == 0)
                root_device_name += 5;
        }
     
        ......
        mount_root();
    out:
        devtmpfs_mount("dev");
        sys_mount(".", "/", NULL, MS_MOVE, NULL);
        sys_chroot(".");
    }

其中saved_root_name变量从环境变量cmdline中解析获取,cat /proc/cmdline查看

    static int __init root_dev_setup(char *line)
    {
        strlcpy(saved_root_name, line, sizeof(saved_root_name));
        return 1;
    }
    __setup("root=", root_dev_setup);

 通过__setup函数解析出cmdline中”root=“后的字符串,即saved_root_name=/dev/mtdblock2。rootfstype获取的值也类似。

    void __init mount_root(void)
    {
        ......
    #ifdef CONFIG_BLOCK
        {
            int err = create_dev("/dev/root", ROOT_DEV);
     
            if (err < 0)
                pr_emerg("Failed to create /dev/root: %d\n", err);
            mount_block_root("/dev/root", root_mountflags);
        }
    #endif
    }

继续流程

 

  prepare_namespace
        mount_root
            mount_block_root
                do_mount_root
                    sys_mount    //sys_mount(name, "/root", fs, flags, data);
    //sys_mount入参定义
    asmlinkage long sys_mount(char __user *dev_name, char __user *dir_name,
                    char __user *type, unsigned long flags,
                    void __user *data);

最终就是把/dev/root设备以squashfs文件系统格式挂载到/root目录下。

 

从设备中可以看出/dev/root软链接到/dev/mtdblock2,就是flash中的rootfs分区 
 

你可能感兴趣的:(linux,运维,服务器)