1 引言
隨著電子產業的不斷發展,基于 ARM 技術的系統設計和開發平臺越來越多地在控制 類、消費類、通信類等電子產品中廣泛應用。從軟件角度上看,構建基于ARM 技術的linux 系統要涉及到引導加載程序、Linux 內核、文件系統、用戶應用程序幾部分的設計。 文件系統是操作系統中用來管理用戶文件的內核軟件層。文件可能存在于磁盤、網絡或 者是一些虛擬的文件。文件系統包括根文件系統和建立于內存設備之上文件系統。根文件系 統是linux 系統的核心部分,包含系統使用的軟件和庫,以及所有用來為用戶提供支持架構 和用戶使用的應用軟件,并作為存儲數據讀寫結果的區域。由于嵌入式設備中Flash 資源很 緊張,如何有效地使用有限的存儲空間是嵌入式開發者必須考慮的,合適的文件系統格式是 解決這一問題的關鍵所在。本文討論了只讀型壓縮Cramfs 根文件系統的特點,并詳細的說 明了NAND FLASH 上建立一個可讀可寫型嵌嵌入式Linux 的Cramfs 根文件系統的新方法。
2 Linux 根文件系統概述
2.1 Linux根文件系統
根文件系統不同于普通文件系統,它是在內核啟動時掛載(mount)的第一個文件系統, 內核代碼映像文件保存在根文件系統中,而系統引導啟動程序會在根文件系統掛載之后把一 些基本的初始化腳本和服務程序等加載到內存中。
Linux 根文件系統是樹型結構組織[1,3],它包含了內核和系統管理所需要的各種文檔和程序等。一般來說,根目錄“/”下頂層目錄都有一些比較固定命名和用途,下面列出一
個Linux 根文件系統中的比較常見的目錄結構。
/bin:存放二進制可執行命令的目錄。
/dev:存放設備文件和目錄。
/etc:存放系統管理和配置文件和目錄。
/home:用戶主目錄,比如用戶user 的主目錄就是/home/user,可以用~user 來表示。
/lib:存放動態鏈接共享庫的目錄。
/sbin:存放系統管理員使用的管理程序的目錄。
/tmp:公用的臨時文件存儲點。
/root:系統管理員的主目錄。
/mnt:用以臨時掛載其他的文件系統。
/proc:虛擬文件系統,可直接訪問這個目錄來獲取系統信息。
/var:某些大文件溢出區。
/usr:存放應用程序和文件。
對于嵌入式 Linux 系統的根文件系統來說,由于受系統資源的限制,一般沒有上述 那么復雜,僅保留一些常用的目錄即可。如/bin、/dev、/etc、/lib、/proc、/var、/tmp、/usr、 /mnt 等[2]。 由于嵌入式系統的設計冗余度小、系統緊湊,通常存儲容量有限,因此,必須選擇 一個合適的根文件系統以使系統運行最佳。目前,嵌入式Linux 根文件系統主要的根文件系 統類型有:Romfs, JFFS2, RAMDISK, YAFFS/YAFFS2, Cramfs, Squashfs 等[1]。本文主要對 Cramfs 根文件系統進行討論。
2.2 Cramfs根文件系統及其在實際應用中存在的問題
Cramfs 是Linux 的創始人 Linus Torvalds 參與開發的一種只讀的壓縮文件系統,它基于 MTD(Memory Technology Device,存儲技術設備)驅動程序。在cramfs 文件系統中,每一頁 (4KB)被單獨壓縮,可以隨機頁訪問,其壓縮比高達2:1,為嵌入式系統節省大量的FLASH 存儲 空間,使系統可通過更低容量的FLASH 存儲相同的文件,從而降低系統成本。
Cramfs 并不 需要一次性地將文件系統中的所有內容都解壓到內存中,而只是在系統需要訪問某個位置的 數據時,立即計算出該數據在Cramfs 中的位置,將其實時地解壓縮到內存中,然后通過對 內存的訪問來獲取文件系統中需要讀取的數據。Cramfs 中的解壓縮以及解壓縮之后內存中 的數據存放位置都是由Cramfs 文件系統本身進行維護的,用戶并不需要了解具體實現過程, 因此這種方式增強了透明度,對開發人員來說,既方便又節省了存儲空間。
由于 Cramfs 是只讀型文件系統,而大多嵌入式應用程序需要在臨時目錄/tmp 進行創建 臨時文件等寫操作,如不對Cramfs 進行配置,則應用程序將不能正常運行,導致系統崩潰。 目前,解決些問題的方法是復合文件系統法,即使用YAFFS/YAFFS2 等可寫型文件系統與 Cramfs 復合而成的文件系統作為嵌入式系統的根文件系統,使Cramfs 根文件系統啟動時掛 載YAFFS/YAFFS2 文件系統,同時將應用程序存放在YAFFS/YAFFS2 文件系統中。這種方 法解決了應用程序對根文件系統的寫操作問題,但由于在通常的根文件系統之外還增加了一 個額外的可寫型文件系統,必然會增大整個根文件系統所占的存儲空間,造成嵌入式系統存 儲資源緊張。本文在實踐的基礎上,通過對Linux Cramfs 根文件系統的研究,發現了一種通 過修改根文件系統啟動腳本和配置文件來實現根文件系統的可讀、可寫性的新方法,它不需 要新增額外的文件系統來支持應用程序的讀、寫要求,而是利用根文件系統本身的特性來構 造一個局部可寫的根文件系統。
3 嵌入式Linux 根文件系統的配置
3.1 Cramfs根文件系統配置文件的分析
Cramfs 根文件系統中的配置文件存放在/etc 目錄下,有22 個文件及文件夾,可分為以 下幾類:
引導和登錄/注銷類,包括/etc/issue、/etc/issue.net、/etc/rc.d/rc、/etc/rc.d/rc.local、 /etc/rc.d/rc.sysinit、/etc/rc.d/rc/rcX.d 等文件,它們主要記錄系統的啟動信息及運行級別等。
文件系統類,包括/etc/mtab、/etc/fstab、/etc/mtools.conf 文件等,它們記錄著系統文 件系統的安裝、卸載信息,系統啟動時可以被安裝的文件系統以及在這些文件系統上所定 義的操作。
系統管理類,包括/etc/group、/etc/nologin、/etc/passwd、/etc/rpmrc、/etc/securetty、 /etc/usertty、/etc/shadow、/etc/shells、/etc/motd 等文件,它們記錄著系統用戶和用戶組的登 錄信息、加密后的用戶帳號密碼信息、用戶組的權限信息等。
網絡類,包括/etc/gated.conf、/etc/networks、/etc/protocols、/etc/gateway、/etc/services、 /etc/inetd.conf、/etc/sysconfig/netword、/etc/recolv.conf、/etc/rpc、/etc/exports 等文件,它們 記錄著系統對網絡接口的配置信息、網絡服務程序、網絡協議、網絡文件系統配置等信息。
系統命令類,包括/etc/lilo.conf、/etc/logrotate.conf、/et/identd.conf、/etc/ld.so.conf、 /etc/inittab、/etc/termcp 等文件,這些文件記錄著要獨占地控制系統的系統命令及動態鏈接 程序配置等信息等。
系統初始化腳本類,包括/etc/init.d 和/etc/rc/init.d 等文件,它們包含一些系統服務類 程序及系統啟動腳本。
根文件系統對掛載文件系統的配置主要由兩個文件決定,即fstab、init.d/rcS[3],fstab 描述了當前系統中已被定義好的可以被系統掛載的文件系統,init.d/rcS 文件描述了系統啟 動時將啟動的命令、服務程序及將要掛載的的文件系統。
由此可見,要使 Cramfs 根文件系統能滿足應用程序的讀寫要求,必須在系統啟動 時為應用程序掛載一個可寫型的文件系統,即配置/etc/fstab 及/etc/init.d/rcS 文件來掛載可寫 型的文件系統。
3.2 為Crmafs文件系統添加應用程序
要發布應用程序到嵌入式系統中,須將應用程序及應用程序所需要的共享庫文件一起 添加到根文件系統中。根文件系統可以根據需要定制,但這樣需要花費大量時間且工作量 大;也可以修改已有的根文件系統,這樣可以節省大量的時間和精力,且不易出錯[4]。
以下 是以藍海微芯LJD-2410DVK-I 嵌入式開發板所提供的root.cramfs 根文件系統為基礎進行修 改和配置的,root.cramfs 是只讀型的文件系統,為了能向里邊加入用戶應用程序,需要將其 重新掛載、壓縮及解壓縮成新的目錄,步驟如下:
在root.cramfs 的相同目錄下新建立一個目錄,如myroot。
在終端中執行命令:mount -o loop root.cramfs myroot, tar –cvf myroot.tar myroot。這兩條 命令的功能分別是將已有的root.cramfs 以塊設備的方式掛載到myroot 并將myroot 壓縮為 myroot.tar。
為不出現目錄重名,將 myroot.tar 拷貝到另一目錄進行解壓:tar –xvf myroot.tar,解壓 出來的文件夾myroot 即是即將作為根文件系統的目錄,它是可讀可寫的。
將已經交叉編譯并調試過的用戶目標程序拷貝到myroot 目錄下的/usr/bin 目錄下,此目 錄為根文件系統中為用戶程序準備的目錄。同時將用戶程序所需要用到的關聯庫文件拷貝到 myroot 目錄下的/usr/lib 目錄下,用戶程序的關聯庫文件可通過ldd 命令查看,ldd 命令格式 如下:
Ldd [選項] 文件
選項有-v:打印ldd 的版本號;-d:執行符號重部署,并報告缺少的目標對象(只對ELF 格式適用);-r:對目標對象和函數執行重新部署,并報告缺少的目標對象和函數(只對ELF 格式適用);-h:幫助信息。
執行如下命令來查看應用程序所關聯的庫:
Ldd –v 程序名
將交叉編譯工具目錄下的/3.4.1/arm-linux/lib 下的libgcc-s.so.*,libstdc++.so.6 復制到 myroot 目錄下的/root/lib 目錄下。
3.3 配置Cramfs根文件系統
為使Cramfs 能支持應用程序的寫操作,需要修改文件系統的配置文件,即/etc 目錄下的 文件。
(1) 修改/etc/init.d/rcS 文件
/etc/init.d/rcS 是Linux 的系統初始化腳本,修改步驟如下:
用 vi 或其它文本工具打開myroot 目錄下的/etc/init.d/rcS 文件;
在文件中增加:
/bin/mount –n –t ramfs ramfs /mnt/yaffs(yaffs 是文件系統的一個目錄);
/bin/mkdir /mnt/yaffs/Qtopia;
/bin/mkdir /mnt/yaffs/Qtopia/tmp。
保存并退出 vi 或文本工具。
根文件系統的配置如圖 1 所示。
圖1 根文件系統的配置
當系統啟動并執行到系統初始化腳本/etc/init.d/rcS 時,mount 命令將/mnt/yaffs 目錄掛載 為ramfs 類型的隨機存儲文件系統,并在此文件系統上建立Qtopia 和Qtopia/tmp 目錄[5], /Qtopia/tmp 目錄即為應用程序可能對文件系統進行寫操作的臨時文件目錄,故應用程序便可 對/mnt/yaffs 目錄進行讀寫操作,保障有讀寫操作要求的應用程序的正常執行。
(2) 修改/etc/profile 文件
用 vi 或其它文本工具打開myroot 目錄下的/etc/profile 文件;
將 PATH 改為:PATH=/bin: /sbin: /usr/sbin: /用戶程序目錄名
在文件中新增以下語句:
LD_LIBRARY_PATH=/lib: /usr/lib: /用戶庫目錄名
export PATH LD_LIBRARY_PATH
保存并退出 vi 或文本工具。
其中,修改環境變量 PATH 的目的是使系統命令/程序目錄擴展到用戶程序目錄,這樣, 當執行用戶應用程序時,系統才能找到相應的共享文件等;修改LD_LIBRARY_PATH 的目的是將系統的共享庫路徑擴展為包含系統程序和用戶程序庫文件路徑的庫文件路徑,以便在 運行用戶程序時能使系統找到應用程序所使用的庫文件。
4 制做Cramfs 根文件系統
制做Cramfs 根文件系統,即是把上述配置好的myroot 目錄文件夾壓縮成為能夠讓Linux 內核支持的Cramfs 格式的映像文件[6]。
制做 Cramfs 根文件系統需要用到mkcramfs 工具,mkcramfs 工具用來創建Cramfs 文件系統,它能把配置好的根文件系統壓縮成Cramfs 格式的根文件系統,壓縮比可達到2:
1,下面是mkcramfs 命令的格式:
mkcramfs [-h] [-e edition] [-i file] [-n name] dirname outfile
其中參數含義分別是-h:顯示幫助信息;-e edition:設置生成的文件系統中的版本 號;-i file:將一個文件映象插入到文件系統中(只能在Linux2.4.0 以后的內核版本中使用); -n name:設定Cramfs 文件系統的名稱;dirname:指明需要被壓縮的整個目錄樹;outfile: 最終輸出的文件。
將mkcramfs 工具拷貝到myroot 相同目錄下,在終端中執行:
mkcramfs myroot myroot.cramfs
此命令所生成的myroot.cramfs 即為可下載到開發板上的根文件系統。
5 結束語
通過對嵌入式Linux 根文件系統結構特點的分析,提出了基于Cramfs 根文件系統配置 的新方法,使嵌入式根文件系統具有了可讀、可寫的功能,同時也減小了根文件系統所占的 存儲空間。
評論
查看更多