陳選育,趙斌鋒,鄧易東,程明,覃波
(中國電子科技集團(tuán)公司第三十四研究所,桂林 541004)
?
MPC8349E平臺(tái)的CRAMFS+JFFS2文件系統(tǒng)設(shè)計(jì)
陳選育,趙斌鋒,鄧易東,程明,覃波
(中國電子科技集團(tuán)公司第三十四研究所,桂林 541004)
首先論述了在MPC8349E平臺(tái)引入CRAMFS+JFFS2兩種文件系統(tǒng)的必要性,然后介紹了兩種嵌入式文件系統(tǒng)開發(fā)工具LTIB和BusyBox,通過這兩種工具的配合使用,提供了一種嵌入式Linux文件系統(tǒng)CRAMFS+JFFS2的設(shè)計(jì)方案,并基于此方案實(shí)現(xiàn)LED控制程序的自啟動(dòng),最后驗(yàn)證了該嵌入式文件系統(tǒng)的運(yùn)行狀況。
MPC8349E;CRAMFS+JFFS2;嵌入式文件系統(tǒng);控制程序
自1991年Linux操作系統(tǒng)誕生后,其應(yīng)用越來越廣泛,這得益于其開源性。與普通的商用實(shí)時(shí)操作系統(tǒng)相比,Linux操作系統(tǒng)資源是免費(fèi)的,從底層的設(shè)備驅(qū)動(dòng)程序到上層的圖形界面環(huán)境均可通過互聯(lián)網(wǎng)獲取[1];可任意裁減,很適合在不同平臺(tái)間移植,縮短了軟件的開發(fā)周期;高度的模塊化使得添加更容易、更方便;通過其本身不斷的完善和提高,支持的處理器種類有PowerPC、ARM、Sparc、MIPS和x86等,使其在嵌入式方面獲得長(zhǎng)足的發(fā)展。
文件系統(tǒng)是Linux操作系統(tǒng)重要的組成部分,用于管理外部存儲(chǔ)設(shè)備上的文件,并為操作系統(tǒng)和用戶提供文件的存取、共享和保護(hù)等功能[2]。目前,在嵌入式Linux系統(tǒng)設(shè)計(jì)中,文件系統(tǒng)常存儲(chǔ)于Flash存儲(chǔ)器,主要的文件系統(tǒng)類型包括JFFS2、YAFFS2、CRAMFS、ROMFS、RAMDISK等[3],往往將CRAMFS、JFFS2文件系統(tǒng)用于NOR Flash,YAFFS文件系統(tǒng)用于NAND Flash。由于MPC8349E-mitx的開發(fā)板NOR Flash存儲(chǔ)空間有限且僅提供單個(gè)的CRAMFS根文件系統(tǒng),它是只讀的、不具有可寫性,而實(shí)際應(yīng)用中除了根文件系統(tǒng)外,還需要具有可讀寫、掉電保護(hù)等功能的其他文件系統(tǒng),保證系統(tǒng)掉電時(shí)數(shù)據(jù)也不會(huì)丟失,故需兩個(gè)或多個(gè)文件系統(tǒng)搭配使用??紤]到JFFS2文件系統(tǒng)一般適合NOR Flash,CRAMFS文件系統(tǒng)具有2:1的壓縮比和只讀性,且讀取速度快,很適合作為受保護(hù)的根文件系統(tǒng)使用。綜合兩種文件系統(tǒng)特點(diǎn)及開發(fā)板存儲(chǔ)器的容量,本文提供了一種實(shí)現(xiàn)“CRAMFS+JFFS2”的文件系統(tǒng)解決方案,并通過該文件系統(tǒng)自啟動(dòng)LED指示燈控制程序。
1.1 開發(fā)平臺(tái)
基于MPC8349E-mitx的硬件平臺(tái),該平臺(tái)的最小系統(tǒng)使用飛思卡爾PowerPC MPC8349E處理器,主頻為667 MHz,外圍存儲(chǔ)芯片包括2片8 MB NOR Flash和4片64 MB DDR1 RAM。系統(tǒng)采用宿主機(jī)加目標(biāo)板的模式,宿主機(jī)是PC機(jī),其操作系統(tǒng)是Vmare-workstation6.0+Red Hat Enterprise 9.0 Linux 2.6.9-5.EL,目標(biāo)板是基于MPC8349E的開發(fā)板,采用的內(nèi)核是嵌入式Linux2.6.13,Boot loader是U-Boot1.1.3。
本設(shè)計(jì)制作文件系統(tǒng)采用兩種工具,分別為L(zhǎng)TIB(Linux Target Image Builder)和BusyBox。LTIB是飛思卡爾公司開發(fā)的一個(gè)使用在不同的目標(biāo)平臺(tái)下,用于開發(fā)和部署B(yǎng)SP(Board Support Packages)的簡(jiǎn)單工具。使用該工具,用戶能夠?yàn)槠淠繕?biāo)平臺(tái)開發(fā)符合GNU/Linux標(biāo)準(zhǔn)的映像。LTIB支持PPC、ARM、Coldfire等多種目標(biāo)架構(gòu),包含超過200個(gè)用戶使用的工具包以及通用跨平臺(tái)的根文件系統(tǒng)。LTIB支持Boot loader和內(nèi)核映像的構(gòu)建,編譯時(shí)可對(duì)交叉編譯工具進(jìn)行選擇,支持RAMDISK和JFFS2 Flash映像的創(chuàng)建。BusyBox是一個(gè)開源項(xiàng)目,遵循GPL V2協(xié)議,集成了一百多個(gè)最常用Linux命令和工具集。它與GNU工具相比,所提供的選項(xiàng)比較少,具有實(shí)用、短小、穩(wěn)定等特點(diǎn),主要應(yīng)用于嵌入式系統(tǒng)[4]。本設(shè)計(jì)選擇使用飛思卡爾公司提供的LTIB.tar.gz集成源碼包,版本為L(zhǎng)TIB 1.24 $,BusyBox源碼版本為BusyBox1.21.2。
在使用過程中需要LTIB和BusyBox兩種工具相互配合,LTIB主要負(fù)責(zé)進(jìn)行內(nèi)核配置、編譯,構(gòu)建內(nèi)核和文件系統(tǒng)映像,BusyBox負(fù)責(zé)制作Linux常用的命令和工具,這是由于用LTIB做好的文件系統(tǒng)有些命令和工具缺失,導(dǎo)致某些應(yīng)用程序可能無法啟動(dòng),需要用BusyBox制作好的可執(zhí)行文件替代LTIB文件系統(tǒng)下相應(yīng)的目錄,它是對(duì)LTIB所制作文件系統(tǒng)一些命令和工具的補(bǔ)充。
1.2 工具包安裝、編譯
BusyBox的軟件包編譯、安裝較簡(jiǎn)單,相關(guān)參考文獻(xiàn)也比較多,本文不再敘述。下面僅介紹LTIB工具的安裝過程,具體步驟如下:
① 首先切換到root用戶,復(fù)制源碼到指定目錄(一般在用戶自己的目錄下)。
$su-root ## 切換身份到root用戶,需要root用戶密碼
# mount /dev/cdrom/mnt/cdrom-o loop ## 掛載光驅(qū)##copy到cxy(新建用戶cxy,根據(jù)用戶名不同更改)的主目錄下
#cp-rf /mnt/cdrom/LTIB-mpc8349e-mitx/home/cxy/
② 創(chuàng)建安裝目錄。
#mkdir-m 777 /usr/local/mpc8349
## 創(chuàng)建安裝LTIB的根目錄
③ 修改普通用戶權(quán)限。由于安裝LTIB需要是普通用戶身份,但部分命令要超級(jí)用戶權(quán)限才行,所以需要執(zhí)行vi增加用戶cxy的權(quán)限。
# /usr/sbin/visudo(或直接用vi命令)## 此命令相對(duì)于vi打開了一個(gè)權(quán)限設(shè)置文件##按i進(jìn)入輸入模式,在最后一行添加如下一行內(nèi)容
cxy ALL=NOPASSWD: /bin/rpm,/opt/freescale/LTIB/usr/bin/rpm
## 按ESC進(jìn)入命令行模式,按:wq保存退出
$ exit## 退出root,回到普通用戶身份cxy
④ 進(jìn)入安裝目錄,開始安裝LTIB。
$ /home/cxy/LTIB-mpc8349e-mitx/install ##安裝完以后,默認(rèn)的交叉編譯環(huán)境為X86
⑤ 建立交叉編譯環(huán)境。在內(nèi)核配置中需配置交叉編譯工具庫,一般有兩種庫供選擇,分別為glibc庫和uclibc庫,可根據(jù)需要選擇,本設(shè)計(jì)采用uclibc庫,具體配置如下:
#vi /etc/bashrc
在最后添加一句:
export PATH=/opt/freescale/usr/local/gcc-3.4.3-uClibc-0.9.28-1/powerpc-linux/bin:$PATH
安裝完重啟后,用#echo $PATH來查看環(huán)境變量設(shè)置是否有/opt/freescale/usr/local/gcc-3.4.3-uClibc-0.9.28-1/powerpc-linux/bin路徑變量[5]。設(shè)置好環(huán)境變量后,就可以對(duì)目標(biāo)板內(nèi)核進(jìn)行配置和編譯了,所用的編譯命令為:
./ltib-preconfig config/platform/mpc8349itx/defconfig-min-fs
文件系統(tǒng)實(shí)現(xiàn)過程,需依賴內(nèi)存技術(shù)設(shè)備(Memory Technology Device,MTD)技術(shù)。MTD是Linux內(nèi)核專門為Flash存儲(chǔ)器開發(fā)的驅(qū)動(dòng)程序子系統(tǒng),該子系統(tǒng)是在Flash硬件驅(qū)動(dòng)和上層文件系統(tǒng)之間提供了一個(gè)抽象的接口,支持JFFS2、CRAMFS文件系統(tǒng),主要負(fù)責(zé)完成Flash存儲(chǔ)器或其他設(shè)備驅(qū)動(dòng)的一些通用工作,而Flash底層硬件驅(qū)動(dòng)只需要在MTD驅(qū)動(dòng)子系統(tǒng)注冊(cè)即可,其他由MTD來完成[6]。通過這種設(shè)計(jì)方式,統(tǒng)一和簡(jiǎn)化了復(fù)雜的Flash存儲(chǔ)器驅(qū)動(dòng)的設(shè)計(jì)。對(duì)開發(fā)者而言,首先需要在內(nèi)核源碼中根據(jù)自己的需求修改MTD分區(qū)表,然后進(jìn)行內(nèi)核編譯和MTD選項(xiàng)的配置。
2.1 修改和配置MTD驅(qū)動(dòng)程序
(1) 修改MTD分區(qū)表
MTD分區(qū)信息在內(nèi)核源碼drivers/mtd/maps/amdnor.c文件中可以發(fā)現(xiàn),如果沒有,可以參照其他NOR Flash文件分區(qū)代碼進(jìn)行修改。在這個(gè)文件里,需定義Flash芯片的首地址、存儲(chǔ)大小、分區(qū)表信息(包括邏輯地址和大小),并將芯片名稱、存儲(chǔ)大小、位寬等填入到一個(gè)struct map_info flagadm_map類型的結(jié)構(gòu)中,同時(shí)將分區(qū)表信息填入到一個(gè)struct flagadm_parts類型的結(jié)構(gòu)數(shù)組中,分區(qū)信息代碼如下所示:
#define FLASH_PHYS_ADDR 0xfe000000
#define FLASH_SIZE 0x01000000
#define FLASH_PARTITION0_ADDR 0x00f00000
#define FLASH_PARTITION0_SIZE 0x00050000
#define FLASH_PARTITION1_ADDR 0x00810000
#define FLASH_PARTITION1_SIZE 0x001F0000
#define FLASH_PARTITION2_ADDR 0x00a00000
#define FLASH_PARTITION2_SIZE 0x00500000
#define FLASH_PARTITION3_ADDR 0x00010000
#define FLASH_PARTITION3_SIZE 0x007F0000
struct map_info flagadm_map = {
.name ="FlagaDM flash device",
.size =FLASH_SIZE,
.bankwidth =2,
};
struct mtd_partition flagadm_parts[] = {
{
.name ="Boot loader",
.offset=FLASH_PARTITION0_ADDR,
.size =FLASH_PARTITION0_SIZE
},
{
.name ="Kernel image",
.offset =FLASH_PARTITION1_ADDR,
.size =FLASH_PARTITION1_SIZE
},
{
.name ="Initial ramdisk image",
.offset =FLASH_PARTITION2_ADDR,
.size =FLASH_PARTITION2_SIZE
},
{
.name ="Persistant storage",
.offset =FLASH_PARTITION3_ADDR,
.size =FLASH_PARTITION3_SIZE
}
};
接下來,在Flash芯片驅(qū)動(dòng)的模塊初始化時(shí),通過調(diào)用ioremap函數(shù)將Flash首地址映射成邏輯地址,然后調(diào)用add_mtd_partitions函數(shù)實(shí)現(xiàn)分區(qū)表的創(chuàng)建和注冊(cè)。
本設(shè)計(jì)中,系統(tǒng)NOR Flash分4個(gè)區(qū),數(shù)組的每一項(xiàng)對(duì)應(yīng)一個(gè)MTD block設(shè)備,即每個(gè)FLASH_PARTITION分區(qū)對(duì)應(yīng)一個(gè)MTD block設(shè)備,MTD block0為U-Boot引導(dǎo)區(qū),MTD block1為內(nèi)核區(qū),MTD block2為CRAMFS根文件系統(tǒng)區(qū),MTD block3為JFFS2文件系統(tǒng)區(qū)。需要注意的是,必須把用作根目錄的設(shè)備作為啟動(dòng)參數(shù)傳遞給內(nèi)核。如果根文件系統(tǒng)區(qū)發(fā)生變更,由MTD block2改為MTD block1,僅需更改U-Boot中啟動(dòng)參數(shù)bootargs的root項(xiàng),將其改為root=/dev/mtdblock1即可,其他設(shè)置不用變動(dòng)。
(2) 配置MTD
在修改完系統(tǒng)分區(qū)代碼后,在編譯內(nèi)核時(shí)需要對(duì)Memory Technology Devices (MTD)選項(xiàng)進(jìn)行配置,必須有Memory Technology Device (MTD) support、MTD partitioning support、Command line partition table parsing、Caching block device access to MTD devices和Mapping drivers for chip acces->HH_NOR_FLASH_SUPPORT支持,其配置界面如圖1所示,其他配置不再詳細(xì)敘述。
圖1 MTD配置界面
用LTIB工具編譯完內(nèi)核后,會(huì)生成內(nèi)核映像、rootfs文件系統(tǒng)及其映像。對(duì)于生成的文件系統(tǒng)及映像,還需要用BusyBox工具進(jìn)行完善,BusyBox配置界面如圖2所示。在配置前需要設(shè)置交叉編譯工具前綴CONFIG_CROSS_COMPILER_PREFIX為powerpc-linux-,確保源碼在PC環(huán)境下編譯。
圖2 BusyBox配置界面
配置編譯完成后,會(huì)在其安裝目錄下生成_install目錄,將該目錄下bin、sbin、usr目錄及l(fā)inuxrc文件替換原來rootfs目錄下相應(yīng)的目錄及文件,替換完后進(jìn)行下一步系統(tǒng)啟動(dòng)腳本配置。
2.2 配置系統(tǒng)啟動(dòng)腳本
Linux內(nèi)核啟動(dòng)完后,首先執(zhí)行根目錄下的linuxrc[7],linuxrc是系統(tǒng)啟動(dòng)時(shí)在內(nèi)存執(zhí)行的啟動(dòng)腳本,用于加載模塊驅(qū)動(dòng)、掛載文件系統(tǒng)、創(chuàng)建文件夾等。它是/bin/busybox的符號(hào)連接,執(zhí)行到腳本最后一行命令“exec /sbin/init”后,跳轉(zhuǎn)到init進(jìn)程,init進(jìn)程讀取/etc/inittab腳本文件中的設(shè)置,開始進(jìn)行系統(tǒng)初始化進(jìn)程。對(duì)inittab腳本進(jìn)行解析可知,一般init進(jìn)程會(huì)依次執(zhí)行系統(tǒng)啟動(dòng)時(shí)執(zhí)行的腳本—>打開一個(gè)登錄會(huì)話—>指定當(dāng)按下ctrl+alt+del鍵執(zhí)行的命令—>關(guān)機(jī)時(shí)執(zhí)行的操作—>系統(tǒng)重啟動(dòng)時(shí)執(zhí)行的命令。其中,系統(tǒng)啟動(dòng)時(shí)運(yùn)行/etc/rc.d/rcs腳本,該腳本設(shè)置各種應(yīng)用程序開機(jī)后自啟動(dòng),也可進(jìn)行其他設(shè)置,如設(shè)置主機(jī)名稱、網(wǎng)絡(luò)接口和IP地址等。本設(shè)計(jì)對(duì)rcs腳本進(jìn)行修改,添加如下內(nèi)容:
if [ $mode = "start" ]
then
if [ -x /etc/config/config.sh ]
then
/etc/config/config.sh
fi
fi
這里調(diào)用了/etc/config/config.sh配置文件,用來實(shí)現(xiàn)對(duì)JFFS2文件系統(tǒng)的掛載和應(yīng)用程序的自啟動(dòng),具體內(nèi)容如下:
#!/bin/sh
echo "Start to mount!"
mount -t JFFS2 /dev/mtdblock3 /a_saveable_dir
usleep 100000
echo "Try to run shell script myconfig.sh!"
if [ -f /a_saveable_dir/config/myconfig.sh ]
then
/a_saveable_dir/config/myconfig.sh
exit 0
fi
echo "Have no shell script myconfig.sh!"
exit 0
上面第三行語句實(shí)現(xiàn)JFFS2文件系統(tǒng)的掛載,通過mount命令將MTD block3設(shè)備掛載到/a_saveable_dir目錄下;第六行語句實(shí)現(xiàn)一個(gè)LED指示燈控制程序的自啟動(dòng),這個(gè)過程首先通過執(zhí)行insmod testled.ko語句加載LED驅(qū)動(dòng)模塊,加載后創(chuàng)建設(shè)備mknod /dev/gpio_drv c 231 0,其中/dev/gpio_drv為設(shè)備名稱,字母c表示為字符設(shè)備,數(shù)字231和0表示主從設(shè)備號(hào),最后執(zhí)行后臺(tái)進(jìn)程,運(yùn)行可執(zhí)行文件./gpio_app &。需要注意一點(diǎn),在實(shí)現(xiàn)掛載JFFS2文件系統(tǒng)之前,先需要在根目錄下建立掛載點(diǎn)a_saveable_dir目錄,目錄存在后才可進(jìn)行APP程序腳本配置。配置完系統(tǒng)啟動(dòng)腳本后,用LTIB工具重新進(jìn)行編譯即可制作完成最終的文件系統(tǒng)映像。最后,將制作好的引導(dǎo)系統(tǒng)、內(nèi)核和文件系統(tǒng)映像燒寫到目標(biāo)板ROM。
圖3所示為文件系統(tǒng)啟動(dòng)后終端控制臺(tái)輸出的部分信息,可以看到config.sh腳本已被調(diào)用。通過查看文件系統(tǒng)結(jié)構(gòu),發(fā)現(xiàn)/a_saveable_dir目錄也已建立,這個(gè)目錄就是JFFS2文件系統(tǒng)區(qū),此目錄可進(jìn)行用戶應(yīng)用程序和數(shù)據(jù)的存取。同時(shí),通過查看進(jìn)程PS命令,可以清楚看到LED自啟動(dòng)控制程序也已經(jīng)執(zhí)行。接下來,通過mount命令檢查目前已掛載的文件系統(tǒng)狀況,可以發(fā)現(xiàn)類型為EXT2和JFFS2的文件出現(xiàn)在列表中,從而驗(yàn)證了本文設(shè)計(jì)的CRAMFS+JFFS2方案達(dá)到預(yù)期要求。
圖3 系統(tǒng)啟動(dòng)后配置信息查看
[1] 鳥哥.鳥哥的Linux私房菜—基礎(chǔ)學(xué)習(xí)編[M].2版.許偉,林彩娥,改編.北京:人民郵電出版社,2007.
[2] 張勇,裘雪紅.嵌入式Linux下JFFS2文件系統(tǒng)的實(shí)現(xiàn)[J].計(jì)算機(jī)技術(shù)與發(fā)展,2006,16(4):138-140.
CRAMFS+JFFS2 File System Based on MPC8349E Platform
Chen Xuanyu,Zhao Binfeng,Deng Yidong,Cheng Ming,Qin Bo
(The 34th Research Institute of CETC,Guilin 541004,China)
In the paper,the necessity of introducing CRAMFS+JFFS2 in MPC8349E platform is described,then the two embedded filesystem development tools LTIB and BusyBox are introduced.Through the cooperation of two tools,a design scheme of embedded Linux file system CRAMFS+JFFS2 is proposed.The LED control procedure of self starting is achieved based on this scheme.Finally,the running status of the embedded file system is proved.
MPC8349E;CRAMFS+JFFS2;embedded file system;control procedures
TP31
A