Linux下磁盤分區(qū)和目錄的關系如下:
- 任何一個分區(qū)都必須掛載到某個目錄上娜庇。
- 目錄是邏輯上的區(qū)分方篮。分區(qū)是物理上的區(qū)分。
- 磁盤Linux分區(qū)都必須掛載到目錄樹中的某個具體的目錄上才能進行讀寫操作藕溅。
- 根目錄是所有Linux的文件和目錄所在的地方,需要掛載上一個磁盤分區(qū)巾表。
Linux操作系統(tǒng)文件系統(tǒng)基礎知識詳解
舉個例子:
有一塊硬盤,分成了4個分區(qū)集币,分別是:
/
/boot
/usr
/windows下的fat
對于/和/boot或者/和/usr调塌,它們是從屬關系惠猿;對于/boot和/usr负间,它們是并列關系。
如果我把windows下的fat分區(qū)掛載到/mnt/winc下姜凄,(掛載政溃??哦态秧,別急董虱,呵呵,一會就講申鱼,一會就講愤诱。)那么對于/mnt/winc和/usr或/mnt/winc和/boot來說,它們是從屬于目錄樹上沒有任何關系的兩個分支捐友。
文件系統(tǒng)指文件存在的物理空間淫半,linux系統(tǒng)中每個分區(qū)都是一個文件系統(tǒng),都有自己的目錄層次結構匣砖。linux會將這些分屬不同分區(qū)的科吭、單獨的文件系統(tǒng)按一定的方式形成一個系統(tǒng)的總的目錄層次結構。一個操作系統(tǒng)的運行離不開對文件的操作猴鲫,因此必然要擁有并維護自己的文件系統(tǒng)对人。
將一個文件系統(tǒng)的頂層目錄掛到另一個文件系統(tǒng)的子目錄上,使它們成為一個整體拂共,稱為掛載牺弄。把該子目錄稱為掛載點。
注意:
1宜狐、掛載點必須是一個目錄势告。
2、一個分區(qū)掛載在一個已存在的目錄上肌厨,這個目錄可以不為空,但掛載后這個目錄下以前的內容將不可用豁陆。
linux文件系統(tǒng)使用索引節(jié)點(inode)來記錄文件信息柑爸。
索引節(jié)點是一個結構,它包含了一個文件的長度盒音、創(chuàng)建及修改時間表鳍、權限、所屬關系祥诽、磁盤中的位置等信息譬圣。一個文件系統(tǒng)維護了一個索引節(jié)點的數(shù)組,每個文件或目錄都與索引節(jié)點數(shù)組中的唯一一個元素對應雄坪。系統(tǒng)給每個索引節(jié)點分配了一個號碼厘熟,也就是該節(jié)點在數(shù)組中的索引號,稱為索引節(jié)點號。
linux文件系統(tǒng)將文件索引節(jié)點號和文件名同時保存在目錄中绳姨。所以登澜,目錄只是將文件的名稱和它的索引節(jié)點號結合在一起的一張表,目錄中每一對文件名稱和索引節(jié)點號稱為一個連接飘庄。
補充一下脑蠕,硬連接在windows里叫junction,軟連接叫shortcut谴仙。并不是windows沒有硬鏈接碾盐,只是不鼓勵使用這個東東。
對于一個文件來說有唯一的索引節(jié)點號與之對應哼审,對于一個索引節(jié)點號孕豹,卻可以有多個文件名與之對應(硬鏈接的原理)。因此春霍,在磁盤上的同一個文件可以通過不同的路徑去訪問它叶眉。
mount根文件系統(tǒng)
linux啟動時,經(jīng)過一系列初始化之后莲趣,需要mount 根文件系統(tǒng)饱溢,為最后運行init進程等做準備,mount 根文件系統(tǒng)有這么幾種方式:
文件系統(tǒng)已經(jīng)存在于硬盤(或者類似的設備)的某個分區(qū)上了潘鲫,kernel根據(jù)啟動的命令行參數(shù)(root=/dev/xxx),直接進行mount肋杖。這里有一個問題,在root文件系統(tǒng)本身還不存在的情況下浊竟,kernel如何根據(jù)/dev/xxx來找到對應的設備呢?注意:根文件系統(tǒng)和其他文件系統(tǒng)的mount方式是不一樣的逐沙,kernel通過直接解析設備的名稱來獲得設備的主、從設備號棚赔,然后就可以訪問對應的設備驅動了徘郭。**所以在init/main.c中有很長一串的root_dev_names(如hda,hdab,sda,sdb,nfs,ram,mtdblock……),通過這個表就可以根據(jù)設備名稱得到設備號胧后。注意抱环,bootloader或內核中設定的啟動參數(shù)(root=/dev/xxx)只是一個代號,實際的根文件系統(tǒng)中不一定存在這個設備文件眶痰!
從軟驅等比較慢的設備上裝載根文件系統(tǒng)梯啤,如果kernel支持ramdisk,在裝載root文件系統(tǒng)時七婴,內核判斷到需要從軟盤(fdx)mount(root=/dev/fd0)察滑,就會自動把文件系統(tǒng)映象復制到ramdisk,一般對應設備ram0户盯,然后在ram0上mount根文件系統(tǒng)魂爪。從源碼看艰管,如果kernel編譯時沒有支持ramdisk,而啟動參數(shù)又是root=/dev/fd0,系統(tǒng)將直接在軟盤上mount撩笆,除了速度比較慢,理論上是可行的(沒試過夕冲,不知道是不是這樣?)
啟動時用到initrd來mount根文件系統(tǒng)泣栈。注意理解ramdisk和initrd這兩個概念弥姻,其實ramdisk只是在ram上實現(xiàn)的塊設備,類似與硬盤操作疼进,但有更快的讀寫速度秧廉,它可以在系統(tǒng)運行的任何時候使用,而不僅僅是用于啟動嚼锄;initrd(boot loader initialized RAM disk)可以說是啟動過程中用到的一種機制澜沟,具體的實現(xiàn)過程也使用ramdisk技術。就是在裝載linux之前刊苍,bootloader可以把一個比較小的根文件系統(tǒng)的映象裝載在內存的某個指定位置濒析,姑且把這段內存稱為initrd(這里是initrd所占的內存,不是ramdisk婴氮,注意區(qū)別)盾致,然后bootloader通過傳遞參數(shù)的方式告訴內核initrd的起始地址和大小(也可以把這些參數(shù)編譯在內核中)罩驻,在啟動階段就可以暫時的用initrd來mount根文件系統(tǒng)护赊。initrd的最初的目的是為了把kernel的啟動分成兩個階段:在kernel中保留最少最基本的啟動代碼砾跃,然后把對各種各樣硬件設備的支持以模塊的方式放在initrd中抽高,這樣就在啟動過程中可以從initrd所mount的根文件系統(tǒng)中裝載需要的模塊透绩。這樣的一個好處就是在保持kernel不變的情況下,通過修改initrd中的內容就可以靈活的支持不同的硬件雏胃。在啟動完成的最后階段志鞍,根文件系統(tǒng)可以重新mount到其他設備上,但是也可以不再 重新mount(很多嵌入式系統(tǒng)就是這樣)统翩。 initrd的具體實現(xiàn)過程是這樣的:bootloader把根文件系統(tǒng)映象裝載到內存指定位置此洲,把相關參數(shù)傳遞給內核,內核啟動時把initrd中的內容復制到ramdisk中(ram0)娶桦,把initrd占用的內存釋放掉汁汗,在ram0上mount根文件系統(tǒng)。從這個過程可以看出祈争,內核需要對同時對ramdisk和initrd的支持(這種需要都編入內核角寸,不能作為模塊)。
嵌入式系統(tǒng)根文件系統(tǒng)
嵌入式系統(tǒng)根文件系統(tǒng)的一種實現(xiàn)方法:對于kernel和根文件系統(tǒng)都存儲在flash中的系統(tǒng)沮峡,一般可以利用linux啟動的initrd的機制亿柑。具體的過程前面已經(jīng)比較清楚了,還有一點就是在啟動參數(shù)中傳遞root=/dev/ram0秘症,這樣使得用initrd進行mount的根文件系統(tǒng)不再切換乡摹,因為這個時候實際的設備就是ram0采转。還有就是initrd的起始地址參數(shù)為虛擬地址,需要和bootloader中用的物理地址對應板熊。