歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux技術

arm+linux fl2440 根文件系統移植(一)

1. 嵌入式存儲系統

1.1. 計算機組成原理

從馮.諾依曼的存儲程序工作原理及計算機的組成來說,計算機由運算器、控制器、存儲器和輸入/輸出設備五大部件組成。其中運算器和控制器統稱為中央處理器(CPU),而存儲系統分成內部存儲器(內存)和外部存儲器(外存)。輸入/輸出設備並非計算機所必需的,如果一個設備具有CPU,內存和外存,我們就可以說它是一台計算機。在很多嵌入式設備上,都沒有輸入/輸出設備,所以從廣義來講,我們的手機,MP3,平板電腦都可以說是一台計算機。
大家可能都聽說過單片機,那麼什麼是單片機呢?其實單片機就是把CPU,內存和外存集成在一個芯片裡面,當然他還包括其他的一些功能模塊。那麼我們聽說的ARM9,ARM11是不是單片機呢?從嚴格意義上來講,他們並不是單片機,雖說在很多ARM處理器裡面都集成得有一個小容量的SRAM,但是由於CPU內部沒有能夠掉電保存數據的外存,所以它就不是單片機。

1.1.1. CPU

中央處理器(英文CentralProcessingUnit,CPU)是一台計算機的運算核心和控制核心,其功能主要是解釋計算機指令以及處理計算機軟件中的數據。CPU由運算器、控制器和寄存器及實現它們之間聯系的數據、控制及狀態的總線構成。差不多所有的CPU的運作原理可分為四個階段:提取/取指(Fetch)、解碼(Decode)、執行(Execute)和寫回(Writeback)。
由於CPU的速度很快,而外存的速度很慢,所以CPU不從外存中取出數據,而是從內存或高速緩沖存儲器(cache)中取出指令,放入指令寄存器,並對指令譯碼,並執行指令。

1.1.2. 存儲器

存儲器是用來存儲程序和數據的部件,對於計算機來說,有了存儲器,才有記憶功能,才能保證正常工作。存儲器的種類很多,按其用途可分為主存儲器(簡稱內存或主存)和輔助存儲器(簡稱外存)。內存是電腦中的主要部件,它是相對於外存而言的,其存儲速度快,掉電後數據丟失,是CPU能直接尋址的存儲空間。內存一般采用半導體存儲單元,包括隨機存儲器(RAM)以及高速緩存(CACHE),而RAM是其中最重要的存儲器。在系統上電前,所有的數據都是存放在外存中的,內存中的數據不可使用。當內存中沒有CPU需要的數據時,會使用DMA(相當於一個協處理器)將數據從外存中調入到內存後,再從內存取數據。

l 隨機存儲器(RAM)
RAM(random access memory)隨機存儲器。存儲單元的內容可按需隨意取出或存入,且存取的速度與存儲單元的位置無關的存儲器。這種存儲器在斷電時將丟失其存儲內容,故主要用於存儲短時間使用的程序。
按照存儲信息的不同,隨機存儲器又分為靜態隨機存儲器(Static RAM,SRAM)和動態隨機存儲器(Dynamic RAM,DRAM)。
SRAM不需要刷新電路即能保存它內部存儲的數據,而DRAM(Dynamic Random Access Memory)每隔一段時間,要刷新充電一次,否則內部的數據即會消失,因此SRAM具有較快的速度和較高的性能,但是SRAM也有它的缺點,即它的集成度較低,相同容量的DRAM內存可以設計為較小的體積,但是SRAM卻需要很大的體積,且功耗較大。SRAM的速度快但昂貴,一般用小容量的SRAM作為更高速CPU和較低速DRAM之間的緩存(cache).
在嵌入式領域,我們常見的DRAM有SDRAM和DDR(DOUBLE
DATA RATE)RAM。SDRAM將CPU與RAM通過一個相同的時鐘鎖在一起,使CPU和RAM能夠共享一個時鐘周期,以相同的速度同步工作,每一個時鐘脈沖的上升沿便開始傳遞數據。DDR
RAM 是SDRAM的更新換代產品,他允許在時鐘脈沖的上升沿和下降沿傳輸數據,這樣不需要提高時鐘的頻率就能加倍提高SDRAM的速度,在PC上上很常見,另外,很多高端的ARM處理器也支持DDR
RAM。
l 高速緩沖存儲器(Cache)
Cache也是我們經常遇到的概念,也就是平常看到的一級緩存(L1 Cache)、二級緩存(L2 Cache)、三級緩存(L3
Cache)這些數據,它位於CPU與內存之間,是一個讀寫速度比內存更快的存儲器。當CPU向內存中寫入或讀出數據時,這個數據也被存儲進高速緩沖存儲器中。當CPU再次需要這些數據時,CPU就從高速緩沖存儲器讀取數據,而不是訪問較慢的內存,當然,如需要的數據在Cache中沒有,CPU會再去讀取內存中的數據。
l 只讀存儲器(ROM)
只讀存儲器(Read-Only Memory)是一種只能讀取資料的存儲器。在制造過程中,將資料以一特制光罩(mask)燒錄於線路中,其資料內容在寫入後就不能更改,所以有時又稱為“光罩式只讀內存”(mask
ROM)。此內存的制造成本較低,常用於電腦中的開機啟動如啟動光盤,在系統裝好的電腦上時,計算機將C盤目錄下的操作系統文件讀取至內存,然後通過cpu調用各種配件進行工作這時系統存放存儲器為RAM。這種屬於COMPACT
DISC激光唱片,光盤就是這種。
l 可編程程序只讀內存(PROM)
可編程程序只讀內存(Programmable ROM,PROM)之內部有行列式的镕絲,是需要利用電流將其燒斷,寫入所需的資料,但僅能寫錄一次。PROM在出廠時,存儲的內容全為1,用戶可以根據需要將其中的某些單元寫入數據0(部分的PROM在出廠時數據全為0,則用
戶可以將其中的部分單元寫入1), 以實現對其“編程”的目的。PROM的典型產品是“雙極性熔絲結構”,如果我們想改寫某些單元,則可以給這些單元通以足夠大的電流,並維持一定的時間,原
先的熔絲即可熔斷,這樣就達到了改寫某些位的效果。另外一類經典的PROM為使用“肖特基二極管”的PROM,出廠時,其中的二極管處於反向截止狀態,還 是用大電流的方法將反相電壓加在“肖特基二極管”,造成其永久性擊穿即可。
l EPROM
可擦出可編程只讀內存(Erasable Programmable Read Only Memory,EPROM)可利用高電壓將資料編程寫入,抹除時將線路曝光於紫外線下,則資料可被清空,並且可重復使用。通常在封裝外殼上會預留一個石英透明窗以方便曝光。
l EEPROM
電可擦出可編程只讀內存(Electrically Erasable Programmable Read Only Memory,EEPROM)之運作原理類似EPROM,但是抹除的方式是使用高電場來完成,因此不需要透明窗。
l FLASH
FLASH表示Flash Memory的意思,即平時所說的“閃存”,全名叫Flash EEPROM Memory。它結合了ROM和RAM的長處,不僅具備電子可擦除可編程(EEPROM)的性能,還可以快速讀取數據(NVRAM的優勢),使數據不會因為斷電而丟失。U盤和MP3裡用的就是這種存儲器。在過去的20年裡,嵌入式系統一直使用ROM(EPROM)作為它們的存儲設備,然而近年來Flash全面代替了ROM(EPROM)在嵌入式系統中的地位,用作存儲Bootloader以及操作系統或者程序代碼,或者直接當硬盤使用(U盤)。

1.2. 嵌入式Flash存儲器

嵌入式硬件系統一般都需要有軟件的支持才能夠正常工作,嵌入式系統需要為軟件提供相應的存儲空間。在以往的單片機系統內,一般使用ROM(Read Only Memory)或EPROM(Erasable Programmable Read Only Memory)存儲程序。由於現有的嵌入式系統越來越復雜,原有的ROM由於容量、靈活性差等的限制,無法滿足日益復雜的應用要求。
閃存(Flash)是電可擦除只讀存儲器(EEPROM)的變種,但兼有RAM和ROM的優點,是一種可在系統(In-System)進行電擦寫,掉電後信息不丟失的存儲器,同時它的高集成度和低成本使它成為市場主流。隨著Flash技術的成熟和普及,一些單片機芯片(如Freescale的8位單片機MC68HC908)已經開始采用片內FLASH取代過去常用的片內ROM或EPROM,使單片機具有了在線編程寫入或擦除的功能。
FLASH在結構和操作方式上與硬盤、EEROM等其他存儲介質有較大區別,他都是只能將1寫為0,而不能將0寫成1。所以在Flash編程之前,必須以塊為單位(塊大小一般為256KB到20MB)將對應的塊擦除,而擦除的過程就是將所有位都寫為1的過程,塊內的所有字節變為0xFF。因此可以說,編程是將相應位寫0的過程,而擦除是將相應位寫1的過程,兩者的執行過程完全相反。而EEPROM能在字節水平上進行刪除和重寫而不是整個芯片擦寫,這樣閃存就比EEPROM的更新速度快。
Flash 芯片是由內部成千上萬個存儲單元組成的,每個單元存儲一個bit。具有低功耗、大容量、擦寫速度快、可整片或分扇區在系統編程(燒寫)、擦除等特點,並且可由內部嵌入的算法完成對芯片的操作,因而在各種嵌入式系統中得到了廣泛的應用。作為一種非易失性存儲器,Flash在系統中通常用於存放程序代碼、常量表以及一些在系統掉電後需要保存的用戶數據等。常用的Flash為8位或16位的數據寬度,編程電壓為單3.3V。主要的生產廠商為INTEL、ATMEL、AMD、HYUNDAI等。Flash技術根據不同的應用場合也分為不同的發展方向,有擅長存儲代碼的NOR
Flash和擅長存儲數據的NAND Flash。

1.3. Norflash和Nandflash的對比

1.3.1. NANDFlash和NORFlash芯片的共性

首先表現在向芯片中寫數據必須先將芯片中對應的內容清空,然後再寫入,即先擦後寫。只不過NORFlash芯片只用擦寫一個字,而NAND需要擦寫整個塊.其次,閃存擦寫的次數都是有限的.當閃存使用接近使用壽命時,經常會出現寫操作失敗;到達使用壽命時,閃存內部存放的數據雖然可以讀,但不能再進行寫操作了.所以為了防止上面問題的發生,不能對某個特定的區域反復進行寫操作.通常NANDFlash可擦寫次數高於NORFlash芯片,但是由於NANDFlash通常是整塊擦寫,塊內的頁面中如果有一位失效整個塊就會失效,而且由於擦寫過程復雜,失敗的概率相對較高,所以從整體上來說NOR的壽命較長.
另一個共性是閃存的讀寫操作不僅僅是一個物理操作,實際上在閃存上存放數據必須使用算法實現,這個模塊一般在驅動程序的MTD'(Memory Technology Drivers)模塊中或者在FTLZ
(Flash Translation Layer)層內實現,具體算法和芯片的生產廠商以及芯片型號有關系.通過比較可以發現,NAND更適用於復雜的文件應用,但是由於NAND芯片的使用相對復雜,所以對文件系統有較高的要求.

1.3.2. NANDFlash和NORFlash芯片的不同

(1)閃存芯片讀寫的基本單位不同
應用程序對NorFlash芯片操作以“字”為基本單位.為了方便對大容量NorFlash閃存的管理,通常將NOR閃存分成大小為128KB或64KB的邏輯塊,有時塊內還分扇區.讀寫時需要同時指定邏輯塊號和塊內偏移.應用程序對NandFlash芯片操作是以“塊”為基本單位.NAND閃存的塊比較小,一般是8KB,然後每塊又分成頁,頁大小一般是512字節.要修改NandFlash芯片中一個字節,必須重寫整個數據塊.
(2)NorFlash閃存是隨機存儲介質,用於數據量較小的場合;NandFlash閃存是連續存儲介質,適合存放大的數據.
(3)由於NorFlash地址線和數據線分開,所以NorFlash芯片可以像SDRAM一樣連在數據線上.NOR芯片的使用類似於通常內存芯片,傳輸效率高,可執行程序可以在芯片內執行(XIP,
eXecute In Place),這樣應用程序可以直接在flash閃存內運行,不必再把代碼讀到系統RAM中.由於NorFlash的這個特點,嵌入式系統中經常將NOR芯片做啟動芯片使用.NandFlash共用地址和數據總線,需要額外聯結一些控制的輸入輸出,所以直接將NAND芯片做啟動芯片比較難.
(4)NandFlash閃存芯片因為共用地址和數據總線的原因,不允許對一個字節甚至一個塊進行的數據清空,只能對一個固定大小的區域進行清零操作;NorFlash芯片可以對字進行操作.所以在處理小數據量的I/O操作的時候的速度要快與NorFlash的速度.比如一塊NorFlash芯片通常寫一個字需要10us,在32位總線上寫512字節需要1280us;NandFlash閃存寫512字節需要的時間包括:512×每字節50ns+10us的尋頁時間+200us的片擦寫時間=234us.
(5)NandFlash閃存的容量比較大,最大容量己達到8G字節.為了方便管理,NandFlash的存儲空間使用了塊和頁兩級存儲體系,也就是說它的存儲空間是二維的,比如K9F5608UOA閃存塊的大小為16K,每頁大小是512字節,每頁還16字節空閒區用來存放錯誤校驗碼空間(也稱為out-of-band,OOB空間).在進行寫操作時,NandFlash閃存每次將一個字節的數據放入內部的緩存區,然後再發出“寫指令”進行寫操作.由於對NandFlash閃存的操作都是以塊和頁為單位的,所以在向NandFlash閃存進行大量數據的讀寫時,NAND的速度要快於NOR閃存.
(6)NorFlash閃存的可靠性要高於NandFlash閃存,是因為NorFlash型閃存的接口簡單,數據操作少,位交換操作少,因此可靠性高,極少出現壞區塊,一般用在對可靠性要求高的地方.NandFlash型閃存接口和操作均相對復雜,位交換操作也很多,關鍵性數據更是需安錯誤探測/錯誤更正(EDC/ECC)算法來確保數據的完整性,因此出現問題的幾率要大得多,壞區塊也是不可避免的,而且由於壞區塊是隨機分布的,連糾錯也無法做到.
(7)NANDFlash一般地址線和數據線共用,對讀寫速度有一定影響;NORFlash閃存數據線和地址線分開,相對而言讀寫速度快一些.
(8)接口對比
NorFlash帶有通用的SRAM接口,可以輕松地掛接在CPU的地址、數據總線上,對CPU的接口要求低。NorFlash的特點是芯片內執行(XIP,eXecute
In Place),這樣應用程序可以直接在flash閃存內運行,不必再把代碼讀到系統RAM中.如uboot中的ro段可以直接在NorFlash上運行,只需要把rw和zi段拷貝到RAM中運行即可.
NandFlash器件使用復雜的I/O口來串行地存取數據,8個引腳用來傳送控制、地址和數據信息。由於時序較為復雜,所以一般CPU最好集成NandFlash控制器.另外由於NandFlash沒有掛接在地址總線上,所以如果想用NandFlash作為系統的啟動盤,就需要CPU具備特殊的功能,如s3c2440在被選擇為NandFlash啟動方式時會在上電時自動讀取NandFlash的4k數據到地址0的SRAM中.如果CPU不具備這種特殊功能,用戶不能直接運行NandFlash上的代碼,那可以采取其他方式,比如好多使用NandFlash的開發板除了使用NandFlash以外,還用上了一塊小的NorFlash來運行啟動代碼.
(9)容量和成本對比
相比起NandFlash來說,NorFlash的容量要小,一般在1~16MByte左右,一些新工藝采用了芯片疊加技術可以把NorFlash的容量做得大一些.在價格方面,NorFlash相比NandFlash來說較高,如目前市場上一片4Mbyte的AM29lv320
NorFlash零售價在20元左右,而一片128MByte的k9f1g08
NandFlash零售價在30元左右. NandFlash生產過程更為簡單,NAND結構可以在給定的模具尺寸內提供更高的容量,這樣也就相應地降低了價格.
(10)可靠性性對比
NandFlash器件中的壞塊是隨機分布的,以前也曾有過消除壞塊的努力,但發現成品率太低,代價太高,根本不劃算.Nand器件需要對介質進行初始化掃描以發現壞塊,並將壞塊標記為不可用.在已制成的器件中,如果通過可靠的方法不能進行這項處理,將導致高故障率。而壞塊問題在NorFlash上是不存在的.
在Flash的位翻轉(一個bit位發生翻轉)現象上,NAND的出現幾率要比NorFlash大得多.這個問題在Flash存儲關鍵文件時是致命的,所以在使用NandFlash時建議同時使用EDC/ECC等校驗算法.
(11)升級對比
NorFlash的升級較為麻煩,因為不同容量的NorFlash的地址線需求不一樣,所以在更換不同容量的NorFlash芯片時不方便.通常我們會通過在電路板的地址線上做一些跳接電阻來解決這樣的問題,針對不同容量的NorFlash.
而不同容量的NandFlash的接口是固定的,所以升級簡單.
(12)讀寫性能對比
寫操作:任何flash器件的寫入操作都只能在空或已擦除的單元內進行.NAND器件執行擦除操作是十分簡單的,而NOR則要求在進行擦除前先要將目標塊內所有的位都寫為1.擦除NOR器件時是以64~128KB的塊進行的,執行一個擦除/寫入操作的時間約為5s.擦除NAND器件是以8~32KB的塊進行的,執行一個擦除/寫入操作最多只需要4ms.讀操作:NOR的讀速度比NAND稍快一些.
(13)文件系統比較
Linux系統中采用MTD來管理不同類型的Flash芯片,包括NandFlash和NorFlash.支持在Flash上運行的常用文件系統有cramfs、jffs、jffs2、yaffs、yaffs2等.cramfs文件系統是只讀文件系統.如果想在Flash上實現讀寫操作,通常在NorFlash上我們會選取jffs及jffs2文件系統,在NandFlash上選用yaffs或yaffs2文件系統.Yaffs2文件系統支持大頁(大於512字節/頁)的NandFlash存儲器.

2. 多種嵌入式文件系統的制作和移植

2.1. 嵌入式Linux文件系統簡介

Linux支持多種文件系統,包括ext2、ext3、vfat、ntfs、iso9660、jffs、romfs和nfs等,為了對各類文件系統
進行統一管理,Linux引入了虛擬文件系統VFS(Virtual File System),為各類文件系統提供一個統一的操作界面和應用編程接口。Linux啟動時,第一個必須掛載的是根文件系統;若系統不能從指定設備上掛載根文件系統,則系統會出錯而退出啟動。之後可以自動或手動掛載其他的文件系統。因此,一個系統中可以同時存在不同的文件系統。
  不同的文件系統類型有不同的特點,因而根據存儲設備的硬件特性、系統需求等有不同的應用場合。在嵌入式Linux應用中,主要的存儲設備為RAM(DRAM, SDRAM)和ROM(常采用FLASH存儲器),常用的基於存儲設備的文件系統類型包括:jffs2,
yaffs, cramfs, romfs, ramdisk, ramfs/tmpfs等。

2.2. 基於RAM的文件系統

2.2.1. initramfs

initramfs在編譯內核的同時被編譯並與內核生成一個映像文件,可以壓縮也可以不壓縮,但是目前只支持cpio包格式。它是根文件系統制作和制作的一種非常簡單的方法,也可以通過執行這個文件系統中的程序引導真正的文件系統,這樣加載根文件系統的工作就不是內核的工作,而是initramfs的工作。由於initramfs使用cpio包格式,所以很容易將一個單一的文件、目錄、node編譯鏈接到系統中去,這樣很簡單的系統中使用起來很方便,不需要另外掛接文件系統。
但是因為cpio包實際是文件、目錄、節點的描述語言包,為了描述一個文件、目錄、節點,要增加很多額外的描述文字開銷,特別是對於目錄和節點,本身很小額外添加的描述文字卻很多,這樣使得cpio包比相應的image文件大很多。

2.2.2. Ramdisk

ramdisk是一種基於內存的虛擬文件系統(並非一個實際的文件系統),它將一部分固定大小(這個大小在編譯內核的make menuconfig時配置)的內存當作硬盤一個分區來使用。ramdisk是一種將實際的文件系統裝入內存的機制,並且可以作為根文件系統,通常我們會使用ext2或ext3文件系統來格式化它。由於ramdisk是在內存中進行操作的,所以我們可以對裡面的文件進行添加,修改,刪除等等操作,但是一掉電,就什麼也沒有了。由於這個特性,我們可以將一些經常被訪問而又不會更改的文件(如只讀的根文件系統)通過Ramdisk放在內存中,這樣可以明顯地提高系統的性能。
在Linux的啟動階段,內核和ramdisk都是由bootloader在啟動時加載至內存的指定位置(),而initrd提供了一套機制,可以將內核映像和根文件系統一起載入內存。initrd是boot
loader initialized RAM disk,顧名思義是在系統初始化引導時候用的ramdisk,它的作用是完善內核的模塊機制,讓內核的初始化流程更具彈性。 

2.2.3. ramfs/tmpfs

Ramfs是Linus Torvalds開發的一種基於內存的文件系統,工作於虛擬文件系統(VFS)層,不能格式化,可以創建多個,在創建時可以指定其最大能使用的內存大小。(實際上,VFS本質上可看成一種內存文件系統,它統一了文件在內核中的表示方式,並對磁盤文件系統進行緩沖。)Ramfs/tmpfs文件系統把所有的文件都放在RAM中,所以讀/寫操作發生在RAM中,可以用ramfs/tmpfs來存儲一些臨時性或經常要修改的數據,例如/tmp和/var目錄,這樣既避免了對Flash存儲器的讀寫損耗,也提高了數據讀寫速度。Ramfs/tmpfs相對於傳統的Ramdisk的不同之處主要在於:不能格式化,文件系統大小可隨所含文件內容大小變化。但他們都不可以像ramdisk一樣作為根文件系統,而只能想procfs,devfs一樣作為偽文件系統使用。

2.2.4. NFS

  NFS網絡文件系統(Network File System)是由Sun開發並發展起來的一項在不同機器、不同操作系統之間通過網絡共享文件的技術。在嵌入式Linux系統的開發調試階段,可以利用該技術在主機上建立基於NFS的根文件系統,掛載到嵌入式設備,可以很方便地修改根文件系統的內容。

2.2.5. 偽文件系統

以上討論的都是基於存儲設備的文件系統(memory-based file system),它們都可用作Linux的根文件系統(除tmpfs和ramfs外)。實際上,Linux還支持邏輯的或偽文件系統(logical
or pseudo file system),例如procfs(proc文件系統),用於獲取系統信息,以及devfs(設備文件系統)和sysfs,用於維護設備文件。

2.3. 基於FLASH的文件系統

  Flash(閃存)作為嵌入式系統的主要存儲媒介,有其自身的特性。Flash的寫入操作只能把對應位置的1修改為0,而不能把0修改為1(擦除Flash就是把對應存儲塊的內容恢復為1),因此,一般情況下,向Flash寫入內容時,需要先擦除對應的存儲區間,這種擦除是以塊(block)為
單位進行的。
  閃存主要有NOR和NAND兩種技術(簡單比較見附錄)。Flash存儲器的擦寫次數是有限的,NAND閃存還有特殊的硬件接口和讀寫時序。因
此,必須針對Flash的硬件特性設計符合應用要求的文件系統;傳統的文件系統如ext2等,用作Flash的文件系統會有諸多弊端。
在嵌入式Linux下,MTD(Memory Technology Device,存儲技術設備)為底層硬件(閃存)和上層(文件系統)之間提供一個統一的抽象接口,即Flash的文件系統都是基於MTD驅動層的(參見下面的Linux下的文件系統結構圖)。使用MTD驅動程序的主要優點在於,它是專門針對各種非易失性存儲器(以閃存為主)而設計的,因而它對Flash有
更好的支持、管理和基於扇區的擦除、讀/寫操作接口。
順便一提,一塊Flash芯片可以被劃分為多個分區,各分區可以采用不同的文件系統;兩塊Flash芯片也可以合並為一個分區使用,采用一個文件系統。即文件系統是針對於存儲器分區而言的,而非存儲芯片。

2.3.1. jffs2

  JFFS文件系統最早是由瑞典Axis Communications公司基於Linux2.0的內核為嵌入式系統開發的文件系統。JFFS2(Journalling
Flash FileSystem v2,日志閃存文件系統版本2 )是RedHat公司基於JFFS開發的閃存文件系統,最初是針對RedHat公司的嵌入式產品eCos開發的嵌入式文件系統,所JFFS2也可以用在Linux,
uCLinux中。它主要用於NOR型閃存,基於MTD驅動層,特點是:可讀寫的、支持數據壓縮的、基於哈希表的日志型文件系統,並提供了崩潰/掉電安全保護,提供“寫平衡”支持等。缺點主要是當文件系統已滿或接近滿時,因為垃圾收集的關系而使jffs2的運行速度大大放慢。
Jffs2不適合用於NAND閃存主要是因為NAND閃存的容量一般較大,這樣導致jffs2為維護日志節點所占用的內存空間迅速增大,另外,jffs2文件系統在掛載時需要掃描整個FLASH的內容,以找出所有的日志節點,建立文件結構,對於大容量的NAND閃存會耗費大量時間。
目前jffs3正在開發中,關於jffs2系列文件系統的使用詳細文檔,可參考MTD補丁包中mtd-jffs-HOWTO.txt。

2.3.2. yaffs

  yaffs/yaffs2(Yet Another Flash File System)是專為嵌入式系統使用NAND型閃存而設計的一種日志型文件系統。與jffs2相比,它減少了一些功能(例如不支持數
據壓縮),所以速度更快,掛載時間很短,對內存的占用較小。另外,它還是跨平台的文件系統,除了Linux和eCos,還支持WinCE,
pSOS和ThreadX等。
  yaffs/yaffs2自帶NAND芯片的驅動,並且為嵌入式系統提供了直接訪問文件系統的API,用戶可以不使用Linux中的MTD與VFS,直接對文件系統操作。當然,yaffs也可與MTD驅動程序配合使用。yaffs與yaffs2的主要區別在於,前者僅支持小頁(512
Bytes) NAND閃存,後者則可支持大頁(2KB) NAND閃存。同時,yaffs2在內存空間占用、垃圾回收速度、讀/寫速度等方面均有大幅提升。

2.3.3. ubifs

無排序區塊圖像文件系統(Unsorted Block Image File System, UBIFS)是用於固態硬盤存儲設備上,並與LogFS相互競爭,作為JFFS2的後繼文件系統之一。真正開始開發於2007年,並於2008年10月第一次加入穩定版本於Linux核心2.6.27版。UBIFS最早在2006年由IBM與Nokia的工程師Thomas
Gleixner,Artem Bityutskiy所設計,專門為了解決MTD(Memory
Technology Device)設備所遇到的瓶頸。由於Nand Flash容量的暴漲,YAFFS等皆無法再去控制Nand
Flash的空間。UBIFS通過子系統UBI處理與MTD
device之間的動作。與JFFS2一樣,UBIFS建構於MTD
device之上,因而與一般的block device不兼容。
JFFS2運行在MTD設備之上,而UBIFS則只能工作於UBI
volume之上。也可以說,UBIFS涉及了三個子系統:
1. MTD 子系統, 提供對flash芯片的訪問接口,MTD子系統提供了MTD
device的概念,比如/dev/mtdx,MTD可以認為是raw
flash
2. UBI subsystem,為flash device提供了wear-leveling和volume
management功能;UBI工作在MTD設備之上,提供了UBI
volume;UBI是MTD設備的高層次表示,對上層屏蔽了一些MTD不得不處理的問題,比如wearing以及壞塊管理
3. UBIFS文件系統,工作於UBI之上
以下是UBIFS的一些特點:
Ø 可擴展性:UBIFS對flash尺寸有著很好的擴展性; 也就是說mount時間,內存消耗以及I/O速度都不依賴與flash尺寸(對於內存消耗並不是完全准確的,但是依賴性非常的低);UBIFS可以很好的適應GB
flashes; 當然UBI本身還有擴展性的問題,無論如何UBI/UBIFS都比JFFS2的可擴展性好,此外如果UBI成為瓶頸,還可以通過升級UBI而不需改變UBIFS
Ø 快速mount:不像JFFS2,UBIFS在mount階段不需要掃描整個文件系統,UBIFS
mount介質的時間只是毫秒級,時間不依賴與flash的尺寸;然而UBI的初始化時間是依賴flash的尺寸的,因此必須把這個時間考慮在內
Ø write-back 支持: 回寫或者叫延遲寫更准確些吧,同JFFS2的write-through(立即寫入內存)相比可以顯著的提高文件系統的吞吐量。
Ø 異常unmount適應度:UBIFS是一個日志文件系統可以容忍突然掉電以及unclean重啟;UBIFS通過replay日志來恢復unclean
unmount,在這種情況下replay會消耗一些時間,因此mount時間會稍微增加,但是replay過程並不會掃描整個flash介質,所以UBIFS的mount時間大概在幾分之一秒。
Ø 快速I/O -即使我們disable write-back(可以在unmount時使用-o
sync mount選項), UBIFS的性能仍然接近JFFS2;記住,JFFS2的同步I/O是非常驚人的,因為JFFS2不需要在flash上維護indexing
data結構, 所以就沒有因此而帶來的負擔; 而UBIFS恰恰是有index數據的。UBIFS之所以夠快是因為UBIFS提交日志的方式:不是把數據從一個地方移動到另外一個位置,而只是把數據的地址加到文件系統的index,然後選擇不同的eraseblock作為新的日志塊,此外還有multi-headed日志方式等技巧。
Ø on-the_flight compression -
存儲在flash介質上的數據是壓縮的;同時也可以靈活的針對單個文件來打開關閉壓縮; 例如,可能需要針對某個特定的文件打開壓縮,或者可能缺省方式下支持壓縮,但是對多媒體文件則關閉壓縮。
Ø 可恢復性
- UBIFS可以從index破壞後恢復;UBIFS中的每一片信息都有一個header來描述,因此可以通過掃描這個flash介質來重構文件系統,這點和JFFS2非常類似;想像一下,如果你擦出了FAT文件系統的FAT表,那麼對於FAT
FS是致命的錯誤,但是如果擦除UBIFS的index,你人然可以重構文件系統,當然這需要一個特定的用戶空間程序來做這個恢復
Ø 完整性 - UBIFS通過寫checksum到flash介質上來保證數據的完整性,UBIFS不會無視損壞文件數據或meta-data;
缺省的情況,UBIFS僅僅檢查meta-data的CRC,但是你可以通過mount選項,強制進行data
CRC的檢查

2.3.4. Cramfs

  Cramfs(Compressed ROM File System)是Linux的創始人Linus
Torvalds參與開發的一種只讀的壓縮文件系統,它也基於MTD驅動程序。在cramfs文件系統中,每一頁(4KB)被單獨壓縮,可以隨機頁訪問,其壓縮比高達2:1,為嵌入式系統節省大量的Flash存儲空間,使系統可通過更低容量的FLASH存儲相同的文件,從而降低系統成本。
Cramfs文件系統以壓縮方式存儲,在運行時解壓縮,所以不支持應用程序以XIP方式運行,所有的應用程序要求被拷到RAM裡去運行,但這並不代表比Ramfs需求的RAM空間要大一點,因為Cramfs是采用分頁壓縮的方式存放檔案,在讀取檔案時,不會一下子就耗用過多的內存空間,只針對目前實際讀取的部分分配內存,尚沒有讀取的部分不分配內存空間,當我們讀取的檔案不在內存時,Cramfs文件系統自動計算壓縮後的資料所存的位置,再即時
解壓縮到RAM中。
另外,它的速度快,效率高,其只讀的特點有利於保護文件系統免受破壞,提高了系統的可靠性。Cramfs映像通常是放在Flash中,但是也能放在別的文件系統裡,使用loopback設備可以把它安裝別的文件系統裡。
由於以上特性,Cramfs在嵌入式系統中應用廣泛。但是它的只讀屬性同時又是它的一大缺陷,使得用戶無法對其內容對進擴充。

2.3.5. Romfs

  傳統型的Romfs文件系統是一種簡單的、緊湊的、只讀的文件系統,不支持動態擦寫保存,按順序存放數據,因而支持應用程序以XIP(eXecute In Place,片內運行)方式運行,在系統運行時,節省RAM空間。uClinux系統通常采用Romfs文件系統。

2.3.6. 其他文件系統

fat/fat32也可用於實際嵌入式系統的擴展存儲器(例如PDA, Smartphone,數碼相機等的SD卡),這主要是為了更好的與最流行的Windows桌面操作系統相兼容。ext2也可以作為嵌入式Linux的文件系統,不過將它用於FLASH閃存會有諸多弊端。

3.
制作根文件系統樹

3.1. 根文件系統簡介

首先要明白的是“什麼是文件系統”,文件系統是對一個存儲設備上的數據和元數據進行組織的機制。這種機制有利於用戶和操作系統的交互。在一篇oracle的技術文章中看到這樣一句話“盡管內核是 Linux 的核心,但文件卻是用戶與操作系統交互所采用的主要工具。這對
Linux 來說尤其如此,這是因為在 UNIX 傳統中,它使用文件 I/O 機制管理硬件設備和數據文件”,這句話我是這樣理解的,在Linux沒有文件系統的話,用戶和操作系統的交互也就斷開了,例如我們使用最多的交互shell,包括其它的一些用戶程序,都沒有辦法運行。在這裡可以看到文件系統相對於Linux操作系統的重要性。下面是Linux文件系統組件的體系結構。
用戶空間包含一些應用程序(例如,文件系統的使用者)和 GNU C 庫(glibc),它們為文件系統調用(打開、讀取、寫和關閉)提供用戶接口。系統調用接口的作用就像是交換器,它將系統調用從用戶空間發送到內核空間中的適當端點。
VFS 是底層文件系統的主要接口。這個組件導出一組接口,然後將它們抽象到各個文件系統,各個文件系統的行為可能差異很大。有兩個針對文件系統對象的緩存(inode 和dentry)。它們緩存最近使用過的文件系統對象。
每個文件系統實現(比如 ext2、JFS 等等)導出一組通用接口,供 VFS 使用。緩沖區緩存會緩存文件系統和相關塊設備之間的請求。例如,對底層設備驅動程序的讀寫請求會通過緩沖區緩存來傳遞。這就允許在其中緩存請求,減少訪問物理設備的次數,加快訪問速度。以最近使用(LRU)列表的形式管理緩沖區緩存。注意,可以使用
sync 命令將緩沖區緩存中的請求發送到存儲媒體(迫使所有未寫的數據發送到設備驅動程序,進而發送到存儲設備)。
當我們在Windows下,提到文件系統時,你的第一反應是想到的是什麼?是不是Windows下的一些Fat32、NTFS等的文件系統的類型。而在Linux中,你可能會想到Ext2、Ext3,但你還必須要有一個根文件系統的概念。根文件系統首先是一種文件系統,該文件系統不僅具有普通文件系統的存儲數據文件的功能,但是相對於普通的文件系統,它的特殊之處在於,它是內核啟動時所掛載(mount)的第一個文件系統,內核代碼的映像文件保存在根文件系統中,系統引導啟動程序會在根文件系統掛載之後從中把一些初始化腳本(如rcS,inittab)和服務加載到內存中去運行。我們要明白文件系統和內核是完全獨立的兩個部分。在嵌入式中移植的內核下載到開發板上,是沒有辦法真正的啟動Linux操作系統的,會出現無法加載文件系統的錯誤。
那麼根文件系統在系統啟動中到底是什麼時候掛載的呢?先將/dev/ram0掛載,而後執行/linuxrc.等其執行完後。切換根目錄,再掛載具體的根文件系統.根文件系統執行完之後,也就是到了Start_kernel()函數的最後,執行init的進程,也就第一個用戶進程。對系統進行各種初始化的操作。如果要能明白這裡的過程的話,可要好好的看看Linux內核源碼了。下圖展示了VFS,內核,文件系統的層次結構:

根文件系統之所以在前面加一個”根“,說明它是加載其它文件系統的”根“,既然是根的話,那麼如果沒有這個根,其它的文件系統也就沒有辦法進行加載的。它包含系統引導和使其他文件系統得以掛載(mount)所必要的文件。根文件系統包括Linux啟動時所必須的目錄和關鍵性的文件,例如Linux啟動時都需要有init目錄下的相關文件,在 Linux掛載分區時Linux一定會找/etc/fstab這個掛載文件等,根文件系統中還包括了許多的應用程序bin目錄等,任何包括這些Linux
系統啟動所必須的文件都可以成為根文件系統。
Linux啟動時,第一個必須掛載的是根文件系統;若系統不能從指定設備上掛載根文件系統,則系統會出錯而退出啟動。成功之後可以自動或手動掛載其他的文件系統。因此,一個系統中可以同時存在不同的文件系統。
在 Linux 中將一個文件系統與一個存儲設備關聯起來的過程稱為掛載(mount)。使用 mount 命令將一個文件系統附著到當前文件系統層次結構中(根)。在執行掛裝時,要提供文件系統類型、文件系統和一個掛裝點。根文件系統被掛載到根目錄下“/”上後,在根目錄下就有根文件系統的各個目錄,文件:/bin /sbin /mnt等,再將其他分區掛接到/mnt目錄上,/mnt目錄下就有這個分區的各個目錄,文件。

3.2. Linux根文件系統中一般有下面的幾個目錄:

1.1.1. /bin目錄

該目錄下的命令可以被root與一般賬號所使用,由於這些命令在掛接其它文件系統之前就可以使用,所以/bin目錄必須和根文件系統在同一個分區中。
/bin目錄下常用的命令有:cat、chgrp、chmod、cp、ls、sh、kill、mount、umount、mkdir、[、test等。其中“[”命令就是test命令,我們在利用Busybox制作根文件系統時,在生成的bin目錄下,可以看到一些可執行的文件,也就是可用的一些命令。

1.1.2. /sbin 目錄

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

1.1.3. /dev目錄

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

1.1.4. /etc目錄

該目錄下存放著系統主要的配置文件,例如人員的賬號密碼文件、各種服務的其實文件等。一般來說,此目錄的各文件屬性是可以讓一般用戶查閱的,但是只有root有權限修改。對於PC上的Linux系統,/etc目錄下的文件和目錄非常多,這些目錄文件是可選的,它們依賴於系統中所擁有的應用程序,依賴於這些程序是否需要配置文件。在嵌入式系統中,這些內容可以大為精減。

1.1.5. /lib目錄

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

1.1.6. home目錄

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

1.1.7. /root目錄

系統管理員(root)的主文件夾,即是根用戶的目錄,與此對應,普通用戶的目錄是/home下的某個子目錄。

1.1.8. /usr目錄

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

1.1.9. /var目錄

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

1.1.10. /proc目錄

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

1.1.11. /mnt目錄

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

1.1.12. /tmp目錄

用於存放臨時文件,通常是空目錄,一些需要生成臨時文件的程序用到的/tmp目錄下,所以/tmp目錄必須存在並可以訪問。
那我們利用Busybox制作根文件系統就是創建這上面的這些目錄,和這些目錄下面的各種文件。
對於嵌入式Linux系統的根文件系統來說,一般可能沒有上面所列出的那麼復雜,比如嵌入式系統通常都不是針對多用戶的,所以/home這個目錄在一般嵌入式Linux中可能就很少用到,而/boot這個目錄則取決於你所使用的BootLoader是否能夠重新獲得內核映象從你的根文件系統在內核啟動之前。一般說來,只有/bin,/dev,/etc,/lib,/proc,/var,/usr這些需要的,而其他都是可選的。
根文件系統一直以來都是所有類Unix操作系統的一個重要組成部分,也可以認為是嵌入式Linux系統區別於其他一些傳統嵌入式操作系統的重要特征,它給
Linux帶來了許多強大和靈活的功能,同時也帶來了一些復雜性。我們需要清楚的了解根文件系統的基本結構,以及細心的選擇所需要的系統庫、內核模塊和應用程序等,並配置好各種初始化腳本文件,以及選擇合適的文件系統類型並把它放到實際的存儲設備的合適位置。
對於嵌入式文件系統的制作和移植而言,它的根文件系統結構基本一樣。因此,對同一個根文件系統,通過相應的工具和方法就能容易生成對應文件系統。下面介紹如何制作一個簡潔的根文件系統。

3.3. 制作根文件系統

制作根文件系統經常會用到根用戶權限,所以需要倍加小心。
Copyright © Linux教程網 All Rights Reserved