因爲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函數如下: