linux檔案系統基礎 rootfs的掛載過程

2021-10-04 09:24:26 字數 3789 閱讀 3194

一、目的

本文主要講述linux3.10檔案系統初始化過程的第一階段:掛載rootfs檔案系統。

rootfs是基於記憶體的檔案系統,所有操作都在記憶體中完成;也沒有實際的儲存裝置,所以不需要裝置驅動程式的參與。基於以上原因,linux在啟動階段使用rootfs檔案系統,當磁碟驅動程式和磁碟檔案系統成功載入後,linux系統會將系統根目錄從rootfs切換到磁碟上的具體檔案系統。

二、主要函式呼叫過程

圖1描述了掛載rootfs的函式呼叫關係(圖中紅色部分),便於後面的分析。

從圖中發現,在掛載rootfs前會先掛載sysfs,這樣做的原因是確保sysfs能夠完整的記錄下裝置驅動模型(目前還看不懂)。

sysfs_init()完成註冊和掛載sysfs檔案系統的功能;init_rootfs()負責註冊rootfs,init_mount_tree()負責掛載rootfs,並將init_task的命名空間與之聯絡起來。

圖1三、linux檔案系統初始化

vfs_cache_init()首先建立並初始化目錄hash表--dentry_hashtable和索引節點hash表--inode_hashtable;然後設定核心可以開啟的最大檔案數;最後呼叫mnt_init()完成sysfs和rootfs檔案系統的註冊和掛載。

linux使用雜湊表儲存目錄和索引節點,以提高目錄和索引節點的查詢效率;dentry_hashtable是目錄雜湊表,inode_hashtable是索引節點雜湊表。

四、掛載sysfs檔案系統

sysfs用來記錄和展示linux驅動模型,sysfs先於rootfs掛載是為全面展示linux驅動模型做好準備。

mnt_init()呼叫sysfs_init()註冊並掛載sysfs檔案系統,然後呼叫kobject_create_and_add()建立"fs"目錄。

2735 err = sysfs_init();

2736 if (err)

2737 printk(kern_warning "%s: sysfs_init error: %d\n",

2738 __func__, err);

2739 fs_kobj = kobject_create_and_add("fs", null);

2740 if (!fs_kobj)

2741 printk(kern_warning "%s: kobj create error\n", __func__);

下面詳細介紹sysfs檔案系統的掛載過程:

1、sysfs_init()呼叫register_filesystem()註冊檔案系統型別sysfs_fs_type,並加入到全域性單鏈表file_systems中。sysfs_fs_type定義如下,.mount成員函式負責超級塊、根目錄和索引節點的建立和初始化工作。

173     err = register_filesystem(&sysfs_fs_type);

174     if (!err)

152 static struct file_system_type sysfs_fs_type = ;
2、sysfs_init()->kern_mount()->vfs_kern_mount()建立並初始化struct mount掛載點,並使用全域性變數sysfs_mnt儲存該掛載點的掛載項(mnt成員)。

783     mnt = alloc_vfsmnt(name);

784     if (!mnt)

785         return err_ptr(-enomem);

3、kern_mount()呼叫sysfs_fs_type的.mount成員sysfs_mount()建立並初始化超級塊、根目錄'/'、根目錄的索引節點等資料結構;並且把超級塊新增到全域性單鏈表super_blocks中,把索引節點新增到hash表inode_hashtable和超級塊的inode鍊錶中。

目前,我們可以得出乙個重要結論:kern_mount()主要完成掛載點、超級塊、根目錄和索引節點的建立和初始化操作,可以看成是乙個原子操作,這個函式以後會頻繁使用。

790     root = mount_fs(type, flags, name, data);
1091 struct dentry *

1092 mount_fs(struct file_system_type *type, int flags, const char *name, void*data)

1093 ;

2、init_mount_tree()呼叫vfs_kern_mount()掛載rootfs檔案系統,詳細的掛載過程與sysfs檔案系統類似,不再贅述。

3、init_mount_tree()呼叫create_mnt_ns()建立命名空間,並設定該命名空間的掛載點為rootfs的掛載點,同時將rootfs的掛載點鏈結到該命名空間的雙向鍊錶中。

2459 static struct mnt_namespace *create_mnt_ns(struct vfsmount *m)

2460

4、init_mount_tree()設定init_task的命名空間,同時呼叫set_fs_pwd()和set_fs_root()設定init_task任務的當前目錄和根目錄為rootfs的根目錄'/'。

2696     ns = create_mnt_ns(mnt);

2697     if (is_err(ns))

2698         panic("can't allocate initial namespace");

2699 

2700     init_task.nsproxy->mnt_ns = ns;

2701     get_mnt_ns(ns);

2702 

2703     root.mnt = mnt;

2704     root.dentry = mnt->mnt_root;

2705 

2706     set_fs_pwd(current->fs, &root);

2707     set_fs_root(current->fs, &root);

通過以上分析,我們發現sysfs和rootfs的區別在於:雖然系統同時掛載了sysfs和rootfs檔案系統,但是只有rootfs處於init_task程序的命名空間內,也就是說系統當前實際使用的是rootfs檔案系統。

此時,sysfs和rootfs在vfs中的檢視如圖3所示:為了突出主要關係,省略了掛載點指向超級塊和根目錄。

從圖中看出,rootfs處於程序的命名空間中,並且程序的fs_struct資料結構的root和pwd都指向了rootfs的根目錄'/',所以使用者實際使用的是rootfs檔案系統。另外,rootfs為vfs提供了'/'根目錄,所以檔案操作和檔案系統的掛載操作都可以在vfs上進行了。

圖3六、總結

linux檔案系統在初始化時,同時掛載了sysfs和rootfs檔案系統,但是只有rootfs處於程序的命名空間中,且程序的root目錄和pwd目錄都指向rootfs的根目錄。至此,linux的vfs已經準備好了根目錄(rootfs的根目錄'/'),此時使用者可以使用系統呼叫對vfs樹進行擴充套件。

Linux檔案系統基礎

一 檔案系統層次分析 由上而下主要分為使用者層 vfs層 檔案系統層 快取層 塊裝置層 磁碟驅動層 磁碟物理層 使用者層 最上面使用者層就是我們日常使用的各種程式,需要的介面主要是檔案的建立 刪除 開啟 關閉 寫 讀等。vfs層 我們知道linux分為使用者態和核心態,使用者態請求硬體資源需要呼叫s...

linux基礎命令 檔案系統

檔案系統 作業系統是通過檔案系統區操作檔案,磁碟或分割槽需要建立檔案系歐諾統後才能被作業系統使用,建立檔案系統的過程叫做格式化 常見檔案系統 fat32,ntfs window的主流檔案系統 ext2,ext3 紅帽4的主要的檔案系統 ext4 紅帽5的主要檔案系統 其中ext3,ext4都是日誌型...

linux檔案系統基礎 檔案系統與根檔案系統

要不我們就統一簡稱為fs和rfs 檔案系統 file system fs 根檔案系統 root file system rfs。首先你考慮一點描述語句 根檔案系統也是一種 檔案系統 可以認為是一種 特殊的 檔案系統 為什麼是叫 特殊的 呢?因為這種 根檔案系統 承載著某些 特殊的功能 其實 檔案系統...