摘 要: 對(duì)以S3C44B0X微處理器為核心的嵌入式系統(tǒng)的特點(diǎn)進(jìn)行了詳細(xì)討論,,分析了在不支持Remap的系統(tǒng)中實(shí)現(xiàn)JFFS2的必要性和可能性,。通過(guò)在MTD中加關(guān)/開(kāi)中斷的方法,實(shí)現(xiàn)了在不支持Remap的系統(tǒng)中建立JFFS2文件系統(tǒng),。
關(guān)鍵詞: S3C44B0X JFFS2 Remap 文件系統(tǒng)
JFFS2文件系統(tǒng)是針對(duì)Flash存儲(chǔ)設(shè)備而專(zhuān)門(mén)設(shè)計(jì)的一種日志文件系統(tǒng),,已在嵌入式系統(tǒng)中得到廣泛應(yīng)用。但是它的實(shí)現(xiàn)通常都依賴(lài)于Remap(地址可重映射)的嵌入式處理器,。本文在不支持地址重映射的嵌入式系統(tǒng)中實(shí)現(xiàn)了JFFS2,,與傳統(tǒng)的實(shí)現(xiàn)相比,它有著其自身的特點(diǎn),。
1 JFFS2文件系統(tǒng)簡(jiǎn)介
ROMFS是?滋Clinux默認(rèn)的根文件系統(tǒng),,它相對(duì)于一般的EXT2文件系統(tǒng)具有節(jié)約空間等優(yōu)點(diǎn),但它卻是一種只讀文件系統(tǒng),,不支持動(dòng)態(tài)擦寫(xiě)和保存,。盡管對(duì)于需要?jiǎng)討B(tài)保存的數(shù)據(jù)可以采用虛擬ram盤(pán)的方法來(lái)保存,可是一旦系統(tǒng)掉電,,ram盤(pán)的內(nèi)容就會(huì)全部丟失,。
為了克服上述問(wèn)題,,人們?cè)O(shè)計(jì)開(kāi)發(fā)了JFFS2文件系統(tǒng)。JFFS文件系統(tǒng)是一種基于Flash的日志文件系統(tǒng),。它在設(shè)計(jì)時(shí)充分考慮了Flash的讀寫(xiě)特性和嵌入式系統(tǒng)用電池供電的特點(diǎn),,在讀取文件時(shí),若遇系統(tǒng)突然掉電,,確保其文件的可靠性不受影響,。后來(lái),JFFS文件系統(tǒng)又進(jìn)行了一系列改進(jìn),,形成了JFFS2文件系統(tǒng),。JFFS2主要改善了存取策略以提高Flash的抗疲勞性,同時(shí)也優(yōu)化了碎片整理性能,,增加了數(shù)據(jù)壓縮功能,。JFFS2的不足是:當(dāng)文件系統(tǒng)已滿或接近滿時(shí),由于垃圾收集方面的原因,,會(huì)引起JFFS2運(yùn)行速度顯著降低,。
JFFS是建立在MTD(Memory Technology Device)基礎(chǔ)之上的文件系統(tǒng),MTD在硬件和上層之間提供一個(gè)抽象接口,。MTD可以理解為Flash的驅(qū)動(dòng)程序,,它主要向上提供兩個(gè)接口,一個(gè)是MTD字符設(shè)備,,另一個(gè)是MTD塊設(shè)備,。通過(guò)這兩個(gè)接口,可以像讀寫(xiě)普通文件一樣對(duì)Flash設(shè)備進(jìn)行讀寫(xiě)操作,。經(jīng)過(guò)簡(jiǎn)單的配置,,MTD在系統(tǒng)啟動(dòng)后可以自動(dòng)識(shí)別支持CFI或JEDEC接口的Flash芯片,并自動(dòng)采用適當(dāng)?shù)拿顓?shù)對(duì)Flash進(jìn)行讀寫(xiě)或擦除,。
MTD支持NOR型和NAND型的Flash,。NOR型Flash的主要特點(diǎn)是芯片內(nèi)執(zhí)行(XIP,eXecute In Place),,應(yīng)用程序可以直接在Flash內(nèi)運(yùn)行,;而NAND型Flash具有存儲(chǔ)密度高和寫(xiě)入/擦除速度快的特點(diǎn)。
2 硬件系統(tǒng)
系統(tǒng)采用Samsung的ARM7TDMI芯片S3C44B0X作為微處理器,。S3C44B0X上的存儲(chǔ)系統(tǒng)地址空間分為8個(gè)存儲(chǔ)體,,每個(gè)存儲(chǔ)體可達(dá)32MB,共計(jì)256MB,。Bank0~Bank5可支持ROM,、SRAM,Bank6和Bank7可支持ROM,、SRAM和FP/EDO/SDRAM等,。Flash芯片采用的是SST公司的NOR型芯片SST39VF160(1×16MB),將它的片選連接到S3C44B0X的nGCS0引腳,,映射到Bank0上,,地址范圍為0x00000000~0x001fffff。SDRAM選用Samsung的16位芯片K4S641632F,,將它與S3C44B0X的GCS6引腳相接,,映射到Bank6上,地址范圍為0x0c000000~0x0c7fffff[6],。
S3C44B0X與其他處理器相比具有一個(gè)很重要的特點(diǎn),,即不支持Remap。圖1是復(fù)位后的S3C44B0X的存儲(chǔ)器映射圖,。一旦Flash和SDRAM的片選與S3C44B0X的nGCSx引腳連接之后,,它們?cè)赟3C44B0X地址空間中的映射位置就固定不變了。而支持地址重映射的處理器則不同,。下面以Samsung的另一款專(zhuān)門(mén)針對(duì)網(wǎng)絡(luò)應(yīng)用的ARM7TDMI處理器S3C4510B為例來(lái)介紹,。
S3C4510B內(nèi)部有幾個(gè)特殊寄存器,用于實(shí)現(xiàn)各存儲(chǔ)介質(zhì)在地址空間中的重映射,。
(1)SYSCFG:該寄存器決定系統(tǒng)管理器中特殊寄存器的起始地址,,以及片內(nèi)SRAM的使用方式和起始地址。
(2)ROMCON0~ROMCON5:分別對(duì)應(yīng)S3C4510B支持的6個(gè)ROM/SRAM/FLASH組,??稍O(shè)置每組的起始物理地址和結(jié)束物理地址。
(3)DRAMCON0~DRAMCON3:分別對(duì)應(yīng)S3C4510B所支持的4個(gè)DRAM組,??稍O(shè)置每組的起始物理地址和結(jié)束物理地址。
可以通過(guò)改變ROMCONx和DRAMCONx寄存器中基指針和尾指針的相應(yīng)位來(lái)方便地實(shí)現(xiàn)S3C4510B系統(tǒng)中地址空間的重映射,。圖2是S3C4510B在實(shí)際應(yīng)用中典型的Remap實(shí)現(xiàn),。
明確了地址可重映射與不可重映射的關(guān)系之后,下面將詳細(xì)討論如何在一個(gè)不支持Remap的系統(tǒng)中實(shí)現(xiàn)JFFS2文件系統(tǒng),。
3 JFFS2文件系統(tǒng)的實(shí)現(xiàn)
3.1 添加Flash的Map文件及芯片參數(shù)
在μClinux-dist/linux-2.4.x/drivers/mtd/maps下添加本系統(tǒng)MPU的Map文件s3c44b0x.c,。該文件包含了系統(tǒng)中Flash的相關(guān)信息,如Flash的起始物理地址,、大小,、數(shù)據(jù)總線的寬度、分區(qū),、讀寫(xiě)函數(shù),、初始化和注銷(xiāo)程序等。具體配置如下:
(1)定義SST39VF160在系統(tǒng)中的起始地址,、大小,、總線寬度:
#define WINDOW_ADDR 0x00000000/*從0地址開(kāi)始*/
#define WINDOW_SIZE 0x00200000/*2MB*/
#define BUSWIDTH 2/*16位*/
(2)定義SST39VF160中字節(jié),、半字及字的讀寫(xiě)操作函數(shù)。
(3)定義SST39VF160中的具體分區(qū),。在本系統(tǒng)中ROMFS文件系統(tǒng)是與內(nèi)核編譯在一起的,,因此定義了三個(gè)分區(qū),分別用于放置引導(dǎo)內(nèi)核啟動(dòng)的BootLoader程序,、經(jīng)過(guò)壓縮的系統(tǒng)內(nèi)核以及需要保存的動(dòng)態(tài)數(shù)據(jù),。其中第三個(gè)區(qū)是要實(shí)現(xiàn)JFFS2文件系統(tǒng)的分區(qū)。
(4)定義用于初始化SST39VF160的int_init init_s3c-44b0x(void)函數(shù),。因?yàn)镾3C44B0X不支持Remap,,所以注釋掉了與ioremap有關(guān)的語(yǔ)句,否則在系統(tǒng)啟動(dòng)時(shí)將返回一個(gè)錯(cuò)誤“Failed to ioremap”,。另外SST39VF160是遵循JEDEC標(biāo)準(zhǔn)的Flash芯片,,在探測(cè)時(shí)直接采用“jedec_probe”。
int _init init_s3c44b0x(void) {
……
/*s3c44b0x_map.map_priv_1 =(unsigned long)ioremap
(WINDOW_ADDR,,WINDOW_SIZE),;
if(!s3c44b0x_map.map_priv_1) {
printk(″Failed to ioremap\n″);
return -EIO,;
}*/
mymtd=do_map_probe(″jedec_probe″,,&s3c44b0x_map);
……
/*iounmap((void *)s3c44b0x_map.map_priv_1),;*/
……
}
(5)定義用于注銷(xiāo)SST39VF160的static void _exit cle-anup_s3c44b0x(void)函數(shù),。同理,注釋掉了與ioremap有關(guān)的語(yǔ)句,。
static void _exit cleanup_s3c44b0x(void)
{ ……
/*if (s3c44b0x_map.map_priv_1) {
iounmap((void *)s3c44b0x_map.map_priv_1),;
s3c44b0x_map.map_priv_1=0;
}*/
}
(6)由于在linux-2.4.x版本中沒(méi)有關(guān)于SST39VF160的定義,,所以需要在μClinux-dist/linux-2.4.x/drivers/mtd/chips/jedec_probe.c中添加SST39VF160的相關(guān)信息,。
3.2 修改MTD配置文件
本節(jié)將論述地址可重映射與不支持地址重映射的嵌入式系統(tǒng)在實(shí)現(xiàn)JFFS2文件系統(tǒng)上的最大差別。當(dāng)ARM處理器發(fā)生異常時(shí),,程序計(jì)數(shù)器PC會(huì)被強(qiáng)制地從異常類(lèi)型對(duì)應(yīng)的固定存儲(chǔ)器地址開(kāi)始執(zhí)行程序,。這些固定的地址稱(chēng)為異常向量(exception vector)。ARM中異常向量定位在32位地址空間的低端,,正常地址范圍為:0x00000000~0x0000001C,。每個(gè)異常向量?jī)?nèi)存放用戶(hù)編寫(xiě)的一條跳轉(zhuǎn)指令,可以轉(zhuǎn)到中斷服務(wù)子程序的首地址,。
在嵌入式系統(tǒng)中,,為了保證系統(tǒng)上電或復(fù)位時(shí)Boot-Loader 程序能夠首先被加載運(yùn)行,F(xiàn)lash只能連接到存儲(chǔ)空間的0地址處。對(duì)于地址可重映射的系統(tǒng),,當(dāng)系統(tǒng)啟動(dòng)后,,可將存放在Flash中的異常向量表的內(nèi)容拷貝到SDRAM的基地址處,然后修改相應(yīng)的寄存器,,將SDRAM 重映射到0地址,。這樣系統(tǒng)產(chǎn)生異常時(shí),,PC就可以直接從SDRAM中取指令,,從而加快了程序的存取速度,縮短了中斷的響應(yīng)時(shí)間,。
對(duì)于不支持地址重映射的系統(tǒng),,異常向量表中的內(nèi)容只能存放在Flash的0地址處。每次系統(tǒng)進(jìn)入異常的時(shí)候,,系統(tǒng)必須從Flash中讀取指令,。這一點(diǎn)對(duì)于實(shí)時(shí)性要求不高的場(chǎng)合影響不大,但要在這樣的系統(tǒng)上實(shí)現(xiàn)JFFS2文件系統(tǒng)則會(huì)出現(xiàn)問(wèn)題,。具體情況為:對(duì)Flash進(jìn)行擦除(erase/eraseall)或?qū)懭?cp/cat/dd)操作時(shí)會(huì)發(fā)生中斷,,這時(shí)系統(tǒng)將強(qiáng)制PC指向異常向量表中的相應(yīng)位置。在不支持地址重映射的系統(tǒng)中,,異常向量表存放在Flash的0地址處,。當(dāng)PC開(kāi)始從Flash中讀取指令時(shí),系統(tǒng)就會(huì)死機(jī),。這是因?yàn)镕lash在擦除或?qū)懭氲臅r(shí)候是不能執(zhí)行讀操作的,,否則就會(huì)發(fā)生不可預(yù)料的錯(cuò)誤,從而不能完成擦除或?qū)懭氩僮?。相反,,在支持地址重映射的系統(tǒng)中就不會(huì)出現(xiàn)這樣的問(wèn)題。因?yàn)樗菑腟DRAM中讀取中斷跳轉(zhuǎn)指令的,,不會(huì)出現(xiàn)在Flash擦除或?qū)懭霑r(shí)執(zhí)行讀操作的情況,。
為了解決在不支持地址重映射的系統(tǒng)中不能對(duì)Flash進(jìn)行正常擦除或?qū)懭氲膯?wèn)題,采用了在MTD最低層的驅(qū)動(dòng)函數(shù)的相應(yīng)位置加關(guān)中斷和開(kāi)中斷的方法,。具體過(guò)程如下:
在μClinux-dist/linux-2.4.x/include/asm/arch/hard-ware.h中定義:
#define INT_ENABLE(n) IntMask &=~(1<<(n))
#define INT_DISABLE(n) IntMask |=(1<<(n))
在μClinux-dist/linux-2.4.x/include/asm/arch/irqs.h中定義:
#define INT_GLOBAL 26 /*總中斷允許位*/
對(duì)μClinux-dist/linux-2.4.x/drivers/mtd/chips/cfi_cmdset_0002.c文件做如下修改:
#include <asm/arch/hardware.h>
#include <asm/arch/irqs.h>
static inline int do_erase_oneblock(struct map_info *map,,
struct flchip *chip,unsigned long adr)
{ ……
INT_DISABLE(INT_GLOBAL),;
……
INT_ENABLE(INT_GLOBAL),;
……
}
static int do_write_oneword(struct map_info *map,struct flchip *chip,,unsigned long adr,,_u32 datum,int fast)
{ ……
INT_DISABLE(INT_GLOBAL),;
……
INT_ENABLE(INT_GLOBAL),;
……
}
3.3 內(nèi)核配置文件設(shè)置
Menuconfig下的配置選項(xiàng)與在支持地址重映射的系統(tǒng)中實(shí)現(xiàn)JFFS2時(shí)的配置相同,。為了避免MTDBLOCK與BLK-MEM主設(shè)備號(hào)的沖突,將μClinux-dist/linux-2.4.x/drivers/block/blkmem.c與μClinux-dist/linux-2.4.x/includee/linux/major.h中的BLKMEM_MAJOR值從“31”改為“30”,,然后添加MTD設(shè)備節(jié)點(diǎn)到/vendors/Samsung/44B0目錄下的Makefile文件中,。
3.4 內(nèi)核的編譯與啟動(dòng)
以上步驟完成之后,運(yùn)行內(nèi)核編譯命令,,啟動(dòng)內(nèi)核,。在超級(jí)終端中將顯示:
s3c44b0x flash device:200000 at 0
Found:SST SST39VF160
number of JEDEC chips:1
Creating 3 MTD partitions on ″S3C44B0X flash device″:
0x00000000-0x00020000:″reserved for bootloader(128k)″
mtd:Giving out device 0 to reserved for bootloader(128k)
0x00020000-0x00140000:″kernel(1152K)″
mtd:Giving out device 1 to kernel(1152K)
0x00140000-0x00200000:″jffs2(768K)″
mtd:Giving out device 2 to jffs2(768K)
3.5 創(chuàng)建和拷貝JFFS2映像文件
/> eraseall /dev/mtd2
Erased 768 Kibyte @ 0 - 100% complete.
/> cd /var/tmp
/var/tmp> mkdir jffs2
/var/tmp> mkdir jffs2/file
/var/tmp> mkfs.jffs2 -d jffs2 -o jffs2.img
/var/tmp> cp jffs2.img /dev/mtd2
3.6 Mount JFFS2分區(qū)
/var/tmp> mount -t jffs2 /dev/mtdblock2 /mnt
/var/tmp> cd /proc
/proc> cat mounts
……
/dev/mtdblock2 /mnt jffs2 rw 0 0 /*mount成功*/
/proc> cd /mnt
/mnt> ls
file
如果希望μClinux每次啟動(dòng)時(shí),自動(dòng)將Flash的第三個(gè)分區(qū)mount到/mnt目錄,,可以在/vendors/Samsung/44B0目錄下的rc文件中加入:mount -t jffs2 /dev/mtdblock2/mnt,。
4 結(jié)束語(yǔ)
本文討論了在不支持Remap的系統(tǒng)中建立JFFS2文件系統(tǒng)的必要性和可能性,并結(jié)合Samsung的S3C44B0X芯片,,通過(guò)在MTD Driver中加關(guān)中斷和開(kāi)中斷的方法實(shí)現(xiàn)了在不支持Remap的系統(tǒng)中建立JFFS2文件系統(tǒng),。由于在MTD Driver中關(guān)中斷和開(kāi)中斷的操作增加了系統(tǒng)的復(fù)雜性,因此推薦采用兩片F(xiàn)lash:一片NOR型Flash用于存儲(chǔ)啟動(dòng)裝載程序和內(nèi)核,;一片NAND型Flash用于存儲(chǔ)用戶(hù)的動(dòng)態(tài)數(shù)據(jù)和應(yīng)用程序,。其中NAND型Flash可以采用新型的YAFFS文件系統(tǒng)。
參考文獻(xiàn)
1 賈東耀.μClinux下Nor Flash的JFFS2文件系統(tǒng)構(gòu)建.國(guó)外電子元器件,,2004,;(9)
2 李桂良,劉發(fā)貴.JFFS2文件系統(tǒng)的關(guān)鍵技術(shù)及其在嵌入式系統(tǒng)中的應(yīng)用.計(jì)算機(jī)應(yīng)用,,2003,;(7)
3 胡晨峰.JFFS2文件系統(tǒng)在μClinux中的應(yīng)用.電子產(chǎn)品世界,2004,;(4)
4 吳明暉,,徐睿,黃健等.基于ARM的嵌入式系統(tǒng)開(kāi)發(fā)與應(yīng)用.北京:人民郵電出版社,,2004
5 王田苗.嵌入式系統(tǒng)設(shè)計(jì)與實(shí)例開(kāi)發(fā).北京:清華大學(xué)出版社,,2002