基于Flash存儲(chǔ)器的嵌入式文件系統(tǒng)設(shè)計(jì)
引言
Flash 存儲(chǔ)器( Flash Memory) 是一種高可靠性、高密度的固態(tài)存儲(chǔ)器件。其存儲(chǔ)方式是完全非易失性的,掉電后可以保存數(shù)據(jù);可以在線寫(xiě)入,并可按頁(yè)連續(xù)字節(jié)寫(xiě)入,存取速度快,所以嵌入式系統(tǒng)通常使用Flash 存儲(chǔ)器作為存儲(chǔ)設(shè)備。 但Flash存儲(chǔ)器也存在著兩個(gè)主要缺陷:一是在重寫(xiě)之前必須進(jìn)行擦除,因?yàn)镕lash 存儲(chǔ)器劃分成很多擦除塊(SectorOErase) ,對(duì)任何一位數(shù)據(jù)進(jìn)行修改必須先擦除整個(gè)塊(Sector) ;二是擦除塊的擦除次數(shù)有限,當(dāng)一個(gè)塊提前達(dá)到擦除次數(shù)上限時(shí), 將導(dǎo)致整個(gè)Flash 存儲(chǔ)器無(wú)法使用。 所以,目前PC 機(jī)上很多成熟的基于磁盤(pán)的文件系統(tǒng)在Flash 存儲(chǔ)器上使用都存在著不足。
嵌入式系統(tǒng)應(yīng)具有的特點(diǎn): 一是高可靠性,在惡劣環(huán)境下系統(tǒng)仍能正常工作;二是低消耗,受成本限制系統(tǒng)設(shè)計(jì)必須量體裁衣,去除冗余;三是高效率,在占用較少資源情況下保證功能需求,這樣就要求算法簡(jiǎn)單,效率高。 而日志文件系統(tǒng)(Log-St ruct ured File System) 在數(shù)據(jù)更新時(shí)無(wú)需將數(shù)據(jù)寫(xiě)入原存儲(chǔ)區(qū)域,適應(yīng)Flash 存儲(chǔ)器無(wú)法進(jìn)行重寫(xiě)這一特點(diǎn)。 目前,針對(duì)Flash 存儲(chǔ)器的缺陷而設(shè)計(jì)的Linux 下的J FFS 文件系統(tǒng),就是采用簡(jiǎn)化的日志文件系統(tǒng)。 J FFS 文件系統(tǒng)將磨損均衡集成于清除機(jī)制之中,在帶來(lái)掉電可恢復(fù)功能的同時(shí),大大減少了塊擦除的次數(shù),提高了文件系統(tǒng)的存取速度和效率。 但是,J FFS 文件系統(tǒng)無(wú)法單獨(dú)使用,或者使用于其它實(shí)時(shí)操作系統(tǒng)中。 對(duì)由于受成本和實(shí)時(shí)性限制而無(wú)法使用Linux 的一些嵌入式系統(tǒng),也就無(wú)法使用J FFS 文件系統(tǒng)。基于上述分析,該嵌入式文件系統(tǒng)適合在開(kāi)源實(shí)時(shí)操作系統(tǒng)(如μC/OS-II) 和無(wú)操作系統(tǒng)的情況下使用。
嵌入式文件系統(tǒng)原理
在日志文件系統(tǒng)中,一個(gè)文件被修改后不是被寫(xiě)入到原來(lái)的存儲(chǔ)空間,而是被加到所有內(nèi)容的后面,象日志一樣被更新,這就是日志文件系統(tǒng)的基本原理。由于同一個(gè)文件在文件系統(tǒng)中會(huì)留下不同的版本,所以系統(tǒng)需要設(shè)置一張表標(biāo)注文件的最新與以前的版本。在內(nèi)容不斷添加時(shí)為不將存儲(chǔ)空間占滿,系統(tǒng)設(shè)計(jì)了一種回收機(jī)制,回收無(wú)效內(nèi)容占用的空間。
日志文件系統(tǒng)在文件更新時(shí)不用將文件寫(xiě)回原來(lái)的地址,這對(duì)Flash 存儲(chǔ)器這種存儲(chǔ)介質(zhì)最為適合。 文中所設(shè)計(jì)的嵌入式文件系統(tǒng)采用了日志文件系統(tǒng)的設(shè)計(jì)原理,以及J FFS 文件系統(tǒng)將磨損均衡集成于清除機(jī)制之中的方法。 該系統(tǒng)將一個(gè)可擦寫(xiě)塊平分為多個(gè)簇,文件的讀寫(xiě)以簇為單位進(jìn)行。簇的狀態(tài)有3 種:臟、干凈和空。臟表示所存內(nèi)容已被置為無(wú)效;干凈表示所存數(shù)據(jù)有效;空表示可以寫(xiě)入數(shù)據(jù)。文件和目錄在該系統(tǒng)中被作為節(jié)點(diǎn),一個(gè)節(jié)點(diǎn)占用若干個(gè)簇,節(jié)點(diǎn)中的內(nèi)容連續(xù)存儲(chǔ),但不能越過(guò)塊邊界存儲(chǔ)。該系統(tǒng)設(shè)置一個(gè)索引節(jié)點(diǎn),保存整個(gè)系統(tǒng)的信息,其中包含保存有各簇狀態(tài)的簇狀態(tài)表。
每一次文件更新后內(nèi)容都將被添加至末尾處,索引節(jié)點(diǎn)也被更新,總是占用最末尾的干凈簇。 回收臟簇時(shí),將所要擦除塊中的干凈簇重寫(xiě)到空簇中,再進(jìn)行塊擦除。 當(dāng)內(nèi)容寫(xiě)至存儲(chǔ)體末端,則從頭部重新開(kāi)始循環(huán)存儲(chǔ)。 所設(shè)計(jì)的文件系統(tǒng)的操作過(guò)程見(jiàn)圖1。
嵌入式文件系統(tǒng)設(shè)計(jì)
Flash 存儲(chǔ)器中的存儲(chǔ)結(jié)構(gòu)
Flash 存儲(chǔ)器中的存儲(chǔ)結(jié)構(gòu)見(jiàn)圖2。 該存儲(chǔ)器中每個(gè)簇的第一個(gè)字作為簇的狀態(tài)字,表示此簇是否為一個(gè)節(jié)點(diǎn)的首簇或空簇。 每個(gè)節(jié)點(diǎn)的首部存放此節(jié)點(diǎn)屬性(文件/目錄/索引節(jié)點(diǎn)) 和節(jié)點(diǎn)標(biāo)識(shí)號(hào)。
索引節(jié)點(diǎn)
索引節(jié)點(diǎn)存放該文件系統(tǒng)的大部分信息。 包括32 位的索引節(jié)點(diǎn)更新號(hào)、一張簇狀態(tài)表、下一個(gè)要被擦除塊的塊號(hào)、給下一個(gè)新建節(jié)點(diǎn)(文件或目錄) 的節(jié)點(diǎn)編號(hào)、系統(tǒng)根目錄信息表。系統(tǒng)每一次更新都會(huì)產(chǎn)生新的索引節(jié)點(diǎn),索引節(jié)點(diǎn)更新號(hào)加1。 按照Flash 存儲(chǔ)器的使用壽命10 年計(jì)算,需要每秒更新136 次以上,才能達(dá)到索引節(jié)點(diǎn)更新號(hào)的上限,所以認(rèn)為擁有最大更新號(hào)的索引節(jié)點(diǎn)為最新的索引節(jié)點(diǎn)。簇狀態(tài)表中對(duì)應(yīng)每一個(gè)簇有兩個(gè)Bit 位,表示各個(gè)簇的狀態(tài)(干凈01 ,臟11 ,空00) 。根目錄信息表存放根目錄下的各個(gè)目錄項(xiàng),每個(gè)目錄項(xiàng)包括:屬性(文件0x1/目錄0x0) 、文件名或目錄名、節(jié)點(diǎn)編號(hào)、此文件(或目錄) 對(duì)應(yīng)節(jié)點(diǎn)的起始簇地址、根目錄表的大小可變。
目錄節(jié)點(diǎn)
目錄節(jié)點(diǎn)存放的內(nèi)容有目錄名,目錄項(xiàng)個(gè)數(shù),及所有目錄項(xiàng)信息。 文件節(jié)點(diǎn)存放文件名,文件大小,文件屬性及文件內(nèi)容,內(nèi)存中的目錄結(jié)構(gòu)見(jiàn)圖3。
內(nèi)存數(shù)據(jù)結(jié)構(gòu)及基本操作
該文件系統(tǒng)載入(Mount ) 后,會(huì)在內(nèi)存中建立一個(gè)系統(tǒng)的映象。該映象包括:索引節(jié)點(diǎn)中的信息、目錄及文件信息、每個(gè)可擦寫(xiě)塊中包含的節(jié)點(diǎn)信息、未存盤(pán)的節(jié)點(diǎn)信息。簇狀態(tài)表、索引節(jié)點(diǎn)更新號(hào)、新節(jié)點(diǎn)編號(hào)、下一擦除塊號(hào)等索引節(jié)點(diǎn)中的內(nèi)容,在內(nèi)存中均作為不同的變量。內(nèi)存中為每個(gè)文件和目錄都建立了映象,數(shù)據(jù)結(jié)構(gòu)見(jiàn)圖4 和圖5。
linux操作系統(tǒng)文章專(zhuān)題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論