5.2.3. 文件系统mount
linux使用系统的根文件系统(system’s root filesystem):它由内核在引导阶段直接安装,并拥有系统初始化脚本及最基本的系统程序.
其他文件系统要么由初始化脚本安装,要么由用户直接安装在已安装文件系统的目录上.作为一个目录树,每个文件系统都有自己的根目录(root directory), 安装文件系统的这个目录称之为安装点(mount point).已安装文件系统属于安装点目录的一个子文件系统.
5.2.3.1. 根文件系统安装
安装根文件系统是系统初始化的关键部分.编译内核时,或者向最初的启动装入程序传递一个合适的”root”选项时,根文件系统可以被指定为/dev目录下的一个设备文件.
安装根文件系统分为两个阶段:
内核安装特殊rootfs文件系统,该文件系统仅提供一个作为初始安装点的空目录
内核在空目录上安装实际根文件系统
注解
为什么内核不怕麻烦,要在安装实际根文件系统之前安装rootfs文件系统呢?rootfs文件系统允许内核改变实际根文件系统.事实上,在某些情况下,内核逐个 安装和卸载几个根文件系统.例如,系统启动时内核把存放在ramdisk中的一个最小文件系统作为根安装.在这个初始根文件系统程序探测信息系统硬件(SSD, EMMC, UFS?), 装入所必须的内核模块后,然后从物理块设备重新安装根文件系统.
注解
用于挂载根文件系统的rootfs事实上是一个ramfs
5.2.3.1.1. rootfs安装
start_kernel
vfs_caches_init
dcache_init
inode_init
files_init
mnt_init
sysfs_init
init_rootfs #注册rootfs文件系统
init_mount_tree #在rootfs中挂载最初的根目录
do_kern_mount("rootfs", 0, "rootfs", NULL)
type->get_sb(type, flags, name, data) #调用文件系统的get_sb方法分配并初始化一个新的超级块
mnt->mnt_sb = sb;
mnt->mnt_parent = mnt
mnt->mnt_namespace = current->namespace
5.2.3.1.2. 实际根文件系统安装
start_kernel
rest_init
init
prepare_namespace #实际的根文件系统安装
mount_devfs
root_device_name = saved_root_name #从启动参数"root"中获取设备文件名
mount_root #窒息向嗯真正的挂载
create_dev("/dev/root", ROOT_DEV, root_device_name) #调用sys_mknod在rootfs中创建设备文件/dev/root
mount_block_root("/dev/root", root_mountflags)
do_mount_root
sys_mount(name, "/root", fs, flags, data)
5.2.3.2. 普通文件系统安装
mount系统调用用来安装普通文件系统,它对应的内核服务例程为 sys_mount
sys_mount
do_mount
do_new_mount
do_kern_mount #进行文件系统安装操作
struct vfsmount *mnt = alloc_vfsmnt(name) #分配文件系统挂载描述符
struct file_system_type *type = get_fs_type(fstype) #获取文件系统类型
sb = type->get_sb(type, flags, name, data); #获取超级块
mnt->mnt_sb = sb;
do_mount_mount #将子文件系统实例与父文件系统装载点进行关联