因为linux支持模块机制,所以我们可以将文件系统编译为模块,所以文件系统系统类型的注册的注册有多种方式:要么已经包含在内核映像中,要么作为一个模块被动态加载。我们关注的重点是rootfs和sysfs,他们其实在系统初始化的时候就注册并安装好了,没有rootfs,linux就没法玩了。以rootfs的注册为例,来分析一下文件系统类型的注册:
在start_kernel-->vfs_caches_init(totalram_pages);
vfs_caches_init函数如下:
void __init vfs_caches_init(unsigned long mempages)
{
unsigned long reserve;
/* Base hash sizes on available memory, with a reserve equal to
150% of current kernel size */
reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
mempages -= reserve;
names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
dcache_init();
inode_init();
files_init(mempages);
mnt_init();
bdev_cache_init();
chrdev_init();
}
其中:
dcache_init(); //目录项的缓存
inode_init(); //索引节点的缓存
files_init(mempages); //file的缓存
mnt_init();
bdev_cache_init(); //块设备的缓存
chrdev_init(); //字符设备的初始化,在《 linux设备模型之字符设备》中会看到字符设备文件是如何建立的。
目前我们关注的重点是mnt_init(),其中有这么几行代码:
err = sysfs_init();
if (err)
printk(KERN_WARNING "%s: sysfs_init error: %d\n",
__func__, err);
fs_kobj = kobject_create_and_add("fs", NULL);
if (!fs_kobj)
printk(KERN_WARNING "%s: kobj create error\n", __func__);
init_rootfs();
init_mount_tree();
可以看到,sysfs_init还在init_rootfs之前,是不是有点奇怪,没有root fs,哪有其他的fs啊?这个在后面我们会明白。
这一次我们只看init_rootfs():
在fs/ramfs/inode.c中:
其实这个注册过程很简单,其实就是加入链表的过程:
为了证明链表的存在:还是要给出file_system_type结构体的全貌:
往后,我们会看到这两个链表各自是怎么串的,串的是什么内容。而在register_filesystem中我们就可以看到struct file_system_type * next;单项链表的形成。
register_filesystem函数如下:
2、初始化fs->fs_supers;
3、查找已经注册过的文件系统,查看准备要注册的文件系统是否已经注册过了,如果注册过,则返回错误。
4、如果没有注册过,则将新的文件系统type添加文件系统列表中。
find_filesystem函数如下: