Linux内核源码分析-安装根文件系统-init_rootfs- init_mount_tree
本文主要参考《深入理解Linux内核》,结合2.6.11.1版的内核代码,分析内核文件子系统中的安装根文件系统函数。
注意:
1、不描述内核同步、错误处理、参数合法性验证相关的内容
2、源码摘自Linux内核2.6.11.1版
3、阅读本文请结合《深入理解Linux内核》第三版相关章节
4、本文会不定时更新
函数调用层次结构
1、init_rootfs
函数功能:
注册rootfs文件系统
函数源码:
该源码包含在文件:fs/ramfs/inode.c
nt __init init_rootfs(void)
{
returnregister_filesystem(&rootfs_fs_type);
}
static struct file_system_typerootfs_fs_type = {
.name = "rootfs",
.get_sb = rootfs_get_sb,
.kill_sb = kill_litter_super,
};
2、init_mount_tree
函数功能:
安装rootfs文件系统
函数源码:
static void __initinit_mount_tree(void)
{
structvfsmount *mnt;
structnamespace *namespace;
structtask_struct *g, *p;
mnt= do_kern_mount("rootfs", 0, "rootfs", NULL);
if(IS_ERR(mnt))
panic("Can'tcreate rootfs");
namespace= kmalloc(sizeof(*namespace), GFP_KERNEL);
if(!namespace)
panic("Can'tallocate initial namespace");
atomic_set(&namespace->count,1); //引用计数器
INIT_LIST_HEAD(&namespace->list);//命名空间中已安装文件系统描述链表头
init_rwsem(&namespace->sem);//保护namespace的读写信号量
list_add(&mnt->mnt_list,&namespace->list);//把rootfs文件系统加入命名空间中已安装文件系统描述链表
namespace->root= mnt; //命名空间根目录的已安装文件系统
mnt->mnt_namespace= namespace; //rootfs文件系统的命名空间
init_task.namespace= namespace; //init进程的命名空间
read_lock(&tasklist_lock);
/*初始化系统中所有进程的地址空间为默认地址空间*/
do_each_thread(g,p) {
get_namespace(namespace);
p->namespace= namespace;
}while_each_thread(g, p);
read_unlock(&tasklist_lock);
set_fs_pwd(current->fs,namespace->root, namespace->root->mnt_root);
set_fs_root(current->fs,namespace->root, namespace->root->mnt_root);
}
函数处理流程:
1、 调用函数do_kern_mount进行实际安装操作,返回新安装文件系统描述符的地址
2、 调用kmalloc分配一个namespace对象,对象地址存放在局部变量namespace中,并初始化namespace、mnt相关数据结构,具体参见注释
3、 初始化系统中所有进程的地址空间为默认地址空间
4、 调用函数set_fs_pwd和set_fs_root初始化当前进程的当前工作目录和根目录
3、do_kern_mount
函数源码:
struct vfsmount *
do_kern_mount(const char *fstype, intflags, const char *name, void *data)
{
structfile_system_type *type = get_fs_type(fstype);
structsuper_block *sb = ERR_PTR(-ENOMEM);
structvfsmount *mnt;
interror;