zoukankan      html  css  js  c++  java
  • 文件系统的挂载(2)---挂载rootfs文件系统

    一、目的

        本文主要讲述linux内核rootfs文件系统的挂载过程,内核版本为3.10。

        rootfs是基于内存的文件系统,没有实际的存储设备,所有操作都在内存中完成。为了保证linux内核的精简性,很多与内核不强相关的功能(设备驱动等)都放在了initrd中,而rootfs文件系统最重要的作用就是为initrd提供了挂载目录:root根目录。

        initrd挂载完成后,内核运行第一个进程initinit进行一系列的初始化操作,包括加载磁盘设备驱动程序和磁盘文件系统,最后把内核的根目录从rootfs的根目录切换到磁盘文件系统的根目录。


    二、主要函数调用过程

        下面给出挂载rootfs文件系统的主要函数调用关系(图中红色部分),便于后面的分析。



    三、分析vfs_cache_init()

        vfs_cache_init()首先建立并初始化目录hashdentry_hashtable和索引节点hashinode_hashtable;然后设置内核可以打开的最大文件数;最后调用mnt_init()负责sysfsrootfs文件系统的建立和挂载。


    四、挂载sysfs文件系统

        sysfs文件系统主要用来展示linux驱动模型,sysfs先于rootfs挂载是为了全面展示linux驱动设备做好准备。

        mnt_init()调用sysfs_init()创建并挂载sysfs文件系统,然后调用kobject_create_and_add()创建“fs”目录。

        下面详细介绍sysfs文件系统的挂载过程:

        1sysfs_init()调用register_filesystem()注册sysfs文件系统类型sysfs_fs_type,并加入到全局单链表file_systems中。sysfs_fs_type定义如下,mount成员函数负责超级块、根目录和索引节点的建立和初始化工作。

     


        2sysfs_init()调用kern_mount()挂载文件系统,kern_mount()调用vfs_kern_mount()创建并初始化挂载点数据结构structmount,并使用全局变量sysfs_mnt保存该挂载点的挂载项(mnt成员)

        3kern_mount()调用sysfs_fs_type的成员函数sysfs_mount()创建并初始化超级块、根目录“/”、根目录的索引节点等数据结构;并且把超级块添加到全局单链表super_blocks中,把索引节点添加到hashinode_hashtable和超级块的inode链表中。

        4vfs_kern_mount()初始化sysfs_mnt挂载点的根目录和超级块。

        5mnt_init()调用kobject_create_and_add()创建“fs”目录。

        通过以上步骤,sysfs文件系统在VFS中的视图如下:其中超级块处在super_blocks单链表中;为了提高查找效率,索引节点处在名为inode_hashtabldhash表中;超级块链接起所有属于该文件系统的索引节点;目录项指向各自的索引节点;挂载点指向超级块和根目录。



    五、挂载rootfs文件系统

        mnt_init()调用init_rootfs()注册rootfs文件系统,然后调用init_mount_tree()挂载rootfs文件系统。

        下面详细介绍rootfs文件系统的挂载过程:

        1mnt_init()调用init_rootfs()注册rootfs文件系统类型rootfs_fs_type,并加入到全局单链表file_systems中。rootfs_fs_type定义如下,mount成员函数负责超级块、根目录和索引节点的建立和初始化工作。


        2init_mount_tree()调用vfs_kern_mount()挂载rootfs文件系统,详细的挂载过程与sysfs文件系统类似,不再熬述。

        3init_mount_tree()调用create_mnt_ns()创建命名空间,并设置该命名空间的挂载点为rootfs的挂载点,同时将rootfs的挂载点链接到该命名空间的双向链表中。

        4init_mount_tree()设置init_task的命名空间,同时调用set_fs_pwd()set_fs_root()设置init_task任务的当前目录和根目录为rootfs的根目录”/”

        通过以上分析,我们发现sysfsrootfs的区别在于:虽然系统同时挂载了sysfsrootfs文件系统,但是只有rootfs处于init_task进程的命名空间内,也就是说系统当前实际使用的是rootfs文件系统。

        此时,sysfsrootfsVFS中的视图如下:为了突出图中主要的关系,省略了挂载点指向超级块和根目录的关系。

        从图中看出,只有rootfs处于进程的命名空间中,并且进程的fs_struct数据结构的rootpwd都指向了rootfs的根目录”/”,所以此时用户的所有文件操作,实际只在rootfs文件系统上生效,而sysfs并不参与。



    六、总结

        linux文件系统在初始化时,同时挂载了sysfsrootfs文件系统,但是只有rootfs处于进程的命名空间中,且进程的root目录和pwd目录都指向rootfs的根目录。至此,linuxVFS已经准备好了根目录(rootfs的根目录”/”),此时用户就可以使用系统调用进行文件和目录的各种操作,对rootfs文件树进行扩展。

  • 相关阅读:
    【POJ 2923】Relocation(状压DP+DP)
    【HDU 2955】Robberies(DP)
    【POJ 2250】Compromise(最长公共子序列LCS)
    【URAL 1917】Titan Ruins: Deadly Accuracy(DP)
    【POJ 1273】Drainage Ditches(网络流)
    HDU2896 病毒侵袭[AC自动机]
    1516. 棋盘上的车[组合数学][状态压缩]
    [HAOI2012] 容易题[母函数]
    [HAOI2012] 高速公路
    [HAOI2012]Road
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3507537.html
Copyright © 2011-2022 走看看