linux中的根文件系統(rootfs的原理和介紹)

linux中有一個讓很多初學者都不是特別清楚的概念,叫做“根文件系統”。我接觸linux前前後後也好幾年了,但是對這個問題,至今也不是特別的清楚,至少沒法給出一個很全面很到位的解釋。於是,今天我們就來理一理這個話題。

一、先交代一下文件系統

在開始討論根文件系統這個話題之前,我們必首先交代一下文件系統這個概念。畢竟,根文件系統只是文件系統中的一種比較特殊的形式而已。根據偉大的百度百科:

文件系統是操作系統用於明確存儲設備(常見的是磁盤,也有基於NAND Flash的固態硬盤)或分區上的文件的方法和數據結構;即在存儲設備上組織文件的方法。操作系統中負責管理和存儲文件信息的軟件機構稱爲文件管理系統,簡稱文件系統。文件系統由三部分組成:文件系統的接口,對對象操作和管理的軟件集合,對象及屬性。從系統角度來看,文件系統是對文件存儲設備的空間進行組織和分配,負責文件存儲並對存入的文件進行保護和檢索的系統。具體地說,它負責爲用戶建立文件,存入、讀出、修改、轉儲文件,控制文件的存取,當用戶不再使用時撤銷文件等。

文件系統的重要性,我想大家都很清楚,不用多說了。這裏有一句話,我覺得非常精闢而且到位的點出了文件系統在linux中的重要性:

儘管內核是linux的核心,但文件卻是用戶與操作系統交互所採用的主要工具。這對linux來說尤其如此,這是因爲在UNIX傳統中,它使用文件I/O機制管理硬件設備和數據文件。

二、什麼是根文件系統

然後來解釋一下“根文件系統”這個名詞的基本概念。同樣引自百度百科的解釋:

根文件系統首先是內核啓動時所mount的第一個文件系統,內核代碼映像文件保存在根文件系統中,而系統引導啓動程序會在根文件系統掛載之後從中把一些基本的初始化腳本和服務等加載到內存中去運行。

展開來細說就是,根文件系統首先是一種文件系統,該文件系統不僅具有普通文件系統的存儲數據文件的功能,但是相對於普通的文件系統,它的特殊之處在於,它是內核啓動時所掛載(mount)的第一個文件系統,內核代碼的映像文件保存在根文件系統中,系統引導啓動程序會在根文件系統掛載之後從中把一些初始化腳本(如rcS,inittab)和服務加載到內存中去運行。我們要明白文件系統和內核是完全獨立的兩個部分。在嵌入式中移植的內核下載到開發板上,是沒有辦法真正的啓動Linux操作系統的,會出現無法加載文件系統的錯誤。

三、根文件系統爲什麼這麼重要

根文件系統之所以在前面加一個”根“,說明它是加載其它文件系統的”根“,那麼如果沒有這個根,其它的文件系統也就沒有辦法進行加載的。

根文件系統包含系統啓動時所必須的目錄和關鍵性的文件,以及使其他文件系統得以掛載(mount)所必要的文件。例如:

init進程的應用程序必須運行在根文件系統上;
根文件系統提供了根目錄“/”;
linux掛載分區時所依賴的信息存放於根文件系統/etc/fstab這個文件中;
shell命令程序必須運行在根文件系統上,譬如ls、cd等命令;
總之:一套linux體系,只有內核本身是不能工作的,必須要rootfs(上的etc目錄下的配置文件、/bin /sbin等目錄下的shell命令,還有/lib目錄下的庫文件等···)相配合才能工作。

Linux啓動時,第一個必須掛載的是根文件系統;若系統不能從指定設備上掛載根文件系統,則系統會出錯而退出啓動。成功之後可以自動或手動掛載其他的文件系統。因此,一個系統中可以同時存在不同的文件系統。在 Linux 中將一個文件系統與一個存儲設備關聯起來的過程稱爲掛載(mount)。使用 mount 命令將一個文件系統附着到當前文件系統層次結構中(根)。在執行掛裝時,要提供文件系統類型、文件系統和一個掛裝點。根文件系統被掛載到根目錄下“/”上後,在根目錄下就有根文件系統的各個目錄,文件:/bin /sbin /mnt等,再將其他分區掛接到/mnt目錄上,/mnt目錄下就有這個分區的各個目錄和文件。

四、如何在內核中掛載根文件系統

init/main.c->

 start_kernel()->vfs_caches_init(totalram_pages)–>

   mnt_init()–>

     /* sysfs用來記錄和展示linux驅動模型,sysfs先於rootfs掛載是爲全面展示linux驅動模型做好準備 */
     /* mnt_init()調用sysfs_init()註冊並掛載sysfs文件系統,然後調用kobject_create_and_add()創建fs目錄 */
     sysfs_init();

     /* init_rootfs()註冊rootfs,然後調用init_mount_tree()掛載rootfs */
     init_rootfs();

     init_mount_tree();

1、sysfs文件系統目前還沒有掛載到rootfs的某個掛載點上,後續init程序會把sysfs掛載到rootfs的sys掛載點上;

2、rootfs是基於內存的文件系統,所有操作都在內存中完成;也沒有實際的存儲設備,所以不需要設備驅動程序的參與。基於以上原因,linux在啓動階段使用rootfs文件系統,當磁盤驅動程序和磁盤文件系統成功加載後,linux系統會將系統根目錄從rootfs切換到磁盤文件系統。

start_kernel
  vfs_caches_init
    mnt_init
      init_rootfs註冊rootfs文件系統
      init_mount_tree 掛載rootfs文件系統
        vfs_kern_mount
          mount_fs
            type->mount其實是rootfs_mount
              mount_nodev
                fill_super 其實是ramfs_fill_super
                  inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
                  sb->s_root = d_make_root(inode);
                    static const struct qstr name = QSTR_INIT(“/”, 1);[1*]
                    __d_alloc(root_inode->i_sb, &name);
          …
          mnt->mnt.mnt_root = root;[2*]
          mnt->mnt.mnt_sb = root->d_sb;[3*]
          mnt->mnt_mountpoint = mnt->mnt.mnt_root;[4*]
          mnt->mnt_parent = mnt;[5*]
root.mnt = mnt;
        root.dentry = mnt->mnt_root;
        mnt->mnt_flags |= MNT_LOCKED;
        set_fs_pwd(current->fs, &root);
        set_fs_root(current->fs, &root);
  …
  rest_init
  kernel_thread(kernel_init, NULL, CLONE_FS);

在執行kernel_init之前,會建立roofs文件系統。

[1*]處設置了根目錄的名字爲“/”;
[2*]處設置了vfsmount中的root目錄;
[3*]處設置了vfsmount中的超級塊;
[4*]處設置了vfsmount中的文件掛載點,指向了自己;
[5*]處設置了vfsmount中的父文件系統的vfsmount爲自己;

五、根文件系統各個常用目錄簡介

正常來說,根文件系統至少包括以下目錄:

/etc/:存儲重要的配置文件。
/bin/:存儲常用且開機時必須用到的執行文件。
/sbin/:存儲着開機過程中所需的系統執行文件。
/lib/:存儲/bin/及/sbin/的執行文件所需的鏈接庫,以及Linux的內核模塊。
/dev/:存儲設備文件。
注:五大目錄必須存儲在根文件系統上,缺一不可。

六、順便說下linux文件系統的常用目錄

Linux文件系統中一般有如下幾個目錄:

/bin目錄
該目錄下存放所有用戶都可以使用的、基本的命令,這些命令在掛接其它文件系統之前就可以使用,所以/bin目錄必須和根文件系統在同一個分區中。
/bin目錄下常用的命令有:cat,chgrp,chmod,cp,ls,sh,kill,mount,umount,mkdir,mknod,test等,我們在利用Busybox製作根文件系統時,在生成的bin目錄下,可以看到一些可執行的文件,也就是可用的一些命令。

/sbin 目錄
該目錄下存放系統命令,即只有管理員能夠使用的命令,系統命令還可以存放在/usr/sbin,/usr/local/sbin目錄下,/sbin目錄中存放的是基本的系統命令,它們用於啓動系統,修復系統等,與/bin目錄相似,在掛接其他文件系統之前就可以使用/sbin,所以/sbin目錄必須和根文件系統在同一個分區中。
/sbin目錄下常用的命令有:shutdown,reboot,fdisk,fsck等,本地用戶自己安裝的系統命令放在/usr/local/sbin目錄下。

/dev目錄
該目錄下存放的是設備文件,設備文件是Linux中特有的文件類型,在Linux系統下,以文件的方式訪問各種設備,即通過讀寫某個設備文件操作某個具體硬件。比如通過”dev/ttySAC0”文件可以操作串口0,通過”/dev/mtdblock1”可以訪問MTD設備的第2個分區。

/etc目錄
該目錄下存放着各種配置文件,對於PC上的Linux系統,/etc目錄下的文件和目錄非常多,這些目錄文件是可選的,它們依賴於系統中所擁有的應用程序,依賴於這些程序是否需要配置文件。在嵌入式系統中,這些內容可以大爲精減。

/lib目錄
該目錄下存放共享庫和可加載(驅動程序),共享庫用於啓動系統。運行根文件系統中的可執行程序,比如:/bin /sbin 目錄下的程序。

/home目錄
用戶目錄,它是可選的,對於每個普通用戶,在/home目錄下都有一個以用戶名命名的子目錄,裏面存放用戶相關的配置文件。

/root目錄
根用戶的目錄,與此對應,普通用戶的目錄是/home下的某個子目錄。

/usr目錄
/usr目錄的內容可以存在另一個分區中,在系統啓動後再掛接到根文件系統中的/usr目錄下。裏面存放的是共享、只讀的程序和數據,這表明/usr目錄下的內容可以在多個主機間共享,這些主要也符合FHS標準的。/usr中的文件應該是隻讀的,其他主機相關的,可變的文件應該保存在其他目錄下,比如/var。/usr目錄在嵌入式中可以精減。

/var目錄
與/usr目錄相反,/var目錄中存放可變的數據,比如spool目錄(mail,news),log文件,臨時文件。

/proc目錄
這是一個空目錄,常作爲proc文件系統的掛接點,proc文件系統是個虛擬的文件系統,它沒有實際的存儲設備,裏面的目錄,文件都是由內核臨時生成的,用來表示系統的運行狀態,也可以操作其中的文件控制系統。

/mnt目錄
用於臨時掛載某個文件系統的掛接點,通常是空目錄,也可以在裏面創建一引起空的子目錄,比如/mnt/cdram /mnt/hda1 。用來臨時掛載光盤、硬盤。

/tmp目錄
用於存放臨時文件,通常是空目錄,一些需要生成臨時文件的程序用到的/tmp目錄下,所以/tmp目錄必須存在並可以訪問。
————————————————
版權聲明:本文爲CSDN博主「leon1741」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/LEON1741/article/details/78159754

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章