嵌入式開發環境介紹
mClinux特點簡介
1. 取消了內存管理單元MMU,具有完整的網絡功能。
2. 完備的文件系統支持,采用了romfs文件系統作為根文件系統,相對于一般的ext2文件系統要求更少的空間。
3. 使用了flat可執行文件格式:elf格式有很大的文件頭,flat文件對文件頭和一些段信息做了簡化。
4. 體積小,可移植性強。
圖1 開發環境示意圖
常見的基于mClinux的嵌入
式系統開發環境的構建方法
在嵌入式系統的開發過程中,通常都要建立交叉編譯環境,圖1為常見的嵌入 式系統開發環境示意圖,基于以太網下的調試一般應將宿主機和用戶板接入到局域網中,本文以mClinux +S3C4510B的開發環境為例進行說明。通常的做法是在宿主機上安裝RedHat Linux操作系統,并同時安裝針對ARM開發的工具鏈arm-elf-tools。這樣,在宿主機上編輯和編譯好的用戶程序,就可以通過以太網,將編譯 后的可執行文件下載到用戶板來運行。下載方式主要有以下幾種。
FTP方式
首先需要打開一個超級終端,設置好相應的通訊參數,再給系統上電,就可以在超級終端里看到mClinux的啟動信息。這里指明宿主機的IP地址是:10.5.22.247,用戶板的IP地址是:10.5.22.8,執行如下命令來配置用戶板的IP:
# ifconfig eth0 10.5.22.8
eth0 指網絡設備。需要注意的是,用戶板的IP地址需和宿主機的IP地址在同一網段,否則難以正常的訪問宿主機。
這時如果可以ping通宿主機,就可以通過FTP方式訪問宿主機的網絡資源了。
接下來選擇用戶程序的存放目錄。應注意,如果用戶板用的是romfs文件系統,那么只有少數幾個目錄可以訪問(如tmp ,var等)。選好存放目錄之后,就可以通過FTP方式訪問宿主機了,鍵入如下命令:
# cd /tmp
# ftp 10.5.22.247
然后輸入用戶名和密碼以確定是否具有訪問權限,成功登陸之后,需要確定文件傳送格式。FTP可以用binary和ascii兩種方式來傳送文件,這里選擇的是binary方式。輸入以下指令來獲取文件:
# binary
# get filename
# bye
執行# bye后就可以退出FTP。這時可以鍵入ls命令來查看文件是否已經傳到選定的目錄下。接下來要做的是改變文件的權限,如果沒有可執行權限,在用戶板中就無法運行程序。
# chmod 755 filename
這里的參數“7”表示擁有讀、寫和執行的權限;“5”僅代表擁有讀和執行的權限。完成以上配置后,就可以用如下命令執行用戶程序了:
# 。/filename
NFS方式
使 用NFS (NetWork File System)方式可以使嵌入式應用程序的開發和調試變得更為方便,并在不同的機器、不同的操作系統間共享文件,因此,NFS在嵌入式開發中得到了廣泛的 應用。目前,在mClinux-2.4-x版本下配置NFS相對比較困難,下面就配置問題進行詳細說明。
服務器(Sever)端的設置
首先需要設置 Linux下的/etc/exports文檔,它是NFS的主要設定文檔。在Linux下的shell終端,進行如下操作:
# vim /etc/exports
將這個默認的空文件修改為只有如下一行內容:
/home/tmp *(rw,no_root_ squash)
這就表示在任何情況下,客戶端都可以訪問服務器端的/home/tmp目錄。
接下來要在服務器端開啟如下的兩個進程:
1.開啟NFS服務
# /etc/rc.d/init.d/nfs start
啟動NFS服務: [ OK ]
Starting NFS quotas: [ OK ]
啟動NFS 守護進程: [ OK ]
啟動NFS mounted : [ OK ]
2.開啟portmap服務
# /etc/rc.d/init.d/portmap start
配置完成后,可用如下辦法簡單測試一下NFS是否配置成功(注意在Linux下要將防火墻關閉):在宿主機上自己mount自己,看是否成功。例如,在宿主機/目錄下執行:
mount 10.5.22.247:/root/ /home/zhang/mount
然后到/home/zhang/mount/目錄下看是否可以列出/root/目錄下的所有文件和目錄。若可以,則說明NFS在服務器端的配置成功。
客戶端(Client)的設置
相 對于Sever端的設置,Client端使用的是 mClinux, 設置起來相對復雜一些,需要對mClinux的內核重新編譯,并進行相關配置。需要設置Customize Kernel Settings 和 Customize Vender/User Setings(NEW)兩項。
1. 對Customize Kernel Settings進行配置
[ * ] Customize Kernel Settings
進入File systems的設置,可以看到Network file systems---,將NFS File system support選中。
2.設置Customize Vender/User Setings(NEW)
[ * ] Customize Vender/User Setings(NEW)
在Customize Vender/User Setings 項目中,選擇Network Applications之后,需要其中的portmap服務,[*] portmap即可。然后選擇mount和umount服務使mClinux支持mount和umount指令。mClinux-2.4-x的內核對 NFS mount的支持不夠,這使得在mClinux上添加NFS服務存在一些困難,而在較新的mClinux版本mClinux-2.6-x中重寫了對 NTFS文件系統的支持。在BusyBox中選擇mount和umount及mount NFS support三項即可,這樣客戶端的配置完成。最后重新編譯內核,指令如下:
# make menuconfig ------------- 內核配
# make dep -------------尋找依存關系
# make clean------------清除以前構造內核時生成的文件
# make lib_only-----------該命令編譯庫文件
# make user_only----------編譯用戶應用程序文件
# make romfs ----------生成romfs文件系統
# make image----------生成romfs.o文件
# make
重 新編譯后,會在。。。/image/目錄下生成image.rom文件,它是壓縮了的內核在rom的映像文件,將其燒寫到用戶板的Flash即可。用戶板 重新啟動之后,新的內核已經開始工作,這時就可以在終端里進行NFS mount了(以在minicom為例)。輸入如下指令:
#mount -t nfs 10.5.22.247:/home/tmp /var/tmp /nfsmount -o nolock
# mount
執行完兩條指令后,在Linux下的minicom里會看到如下信息:
Rootfs on / type rootfs (rw)
/dev/rom0 on / type rootfs (ro)
/proc on/proc type proc (rw)
/dev/ram0 on/var type ext2 (rw)
/dev/ram1 on /disk type ext2 (rw)
10.5.22.247:/home/tmp on /var/tmp type nfs (rw,v3,rsize=8192,hard, udp,nolock,addr=10.5.22.2)
這樣就將宿主機的/home/tmp目錄掛載到了用戶板的/var/tmp目錄。
結語
通過以上兩種方式的比較,可以看到,就開發的效率來說,NFS的方式明顯具有優勢。畢竟,用戶開發的程序往往不能一次就調試成功,采用 NFS方式使得多人同時開發一個程序成為可能。事實上,除了文中提到的兩種方式以外,還有其它以太網環境下的嵌入式開發手段,如telnet等,限于篇 幅,不再詳細介紹。
嵌入式文件系統要求分析
嵌入式linux下常見的文件系統
? RomFS:只讀文件系統,可以放在ROM空間,也可以在系統的RAM中,嵌入式linux中常用來作
根文件系統
? RamFS:利用VFS自身結構而形成的內存文件系統,使用系統的RAM空間
? JFFS/JFFS2:為Flash設計的日志文件系統
? Yaffs:專門為Nand Flash設計
? proc:為內核和內核模塊將信息發送給進程提供一種機制,可以查看系統模塊裝載的信息
? devFS:設備文件系統
Linux上的Ext2fs
? 支持4 TB 存儲、文件名稱最長1012 字符
? 可選擇邏輯塊
? 快速符號鏈接
? Ext2不適合flash設備
? 是為象IDE 設備那樣的塊設備設計的,邏輯塊大小必須是512 byte、1 KB、2KB等
? 沒有提供對基于扇區的擦除/寫操作的良好管理
? 如果在一個扇區中擦除單個字節,必須將整個扇區復制到RAM,然后擦除,再重寫入
? 在出現電源故障時,Ext2fs 是不能防止崩潰的
? 文件系統不支持損耗平衡,縮短了flash的壽命
jffs/jffs2文件系統的優缺點
? 日志文件系統
? 提供了更好的崩潰、掉電安全保護
? jffs2支持對flash的均勻磨損
? 在扇區級別上執行閃存擦除/寫/讀操作要比Ext2文件系統好
? 文件系統接近滿時,JFFS2 會大大放慢運行速度——垃圾收集
Nand上yaffs文件系統的優勢
? 專門為Nand flash設計的日志文件系統
? jffs/jffs2不適合大容量的Nand flash
? jffs的日志通過jffs_node建立在RAM中,占用RAM空間:對于128MB的Nand大概需要4MB的空間來維護節點
? 啟動的時候需要掃描日志節點,不適合大容量的Nand flash
? FAT系統沒有日志
編譯yaffs文件系統
? mtd的最新補丁升級?
? 接口更新,適合與yaffs
? 與原有的mtd驅動程序不兼容,需要重寫
? 如果使用舊mtd驅動需要定義Makefile中MTD_OLD = -DCONFIG_YAFFS_USE_OLD_MTD
? 參考文檔: yaffs-rootfs-howto
? 最新版的yaffs網站:http://www.aleph1.co.uk/armlinux/projects/yaffs
使用yaffs文件系統
? 通過cat /proc/yaffs命令可以看到yaffs系統的相關信息
? mount -t yaffs /dev/mtdblock/0 /mnt/yaffs
關于Linux文件系統
JFFS 全稱為:The Journalling Flash File System(日志閃存文件系統)最初由瑞典的 Axis Communications 開發,Red Hat 的 David Woodhouse 對它進行了改進。作為用于微型嵌入式設備的原始閃存芯片的實際文件系統而出現。JFFS文件系統是日志結構化的,這意味著它基本上是一長列節點。每個節點包含有關文件的部分信息 — 可能是文件的名稱、也許是一些數據。相對于 Ext2 fs,JFFS 因為有以下這些優點而在無盤嵌入式設備中越來越受歡迎:
1 JFFS 在扇區級別上執行閃存擦除/寫/讀操作要比 Ext2 文件系統好。
2 JFFS 提供了比 Ext2 更好的崩潰/掉電安全保護。當需要更改少量數據時,Ext2 文件系統將整個扇區復制到內存(DRAM)中,在內存中合并新數據,并寫回整個扇區。這意味著為了更改單個字,必須對整個扇區(64 KB)執行讀/擦除/寫例程 — 這樣做的效率非常低。要是運氣差,當正在 DRAM 中合并數據時,發生了電源故障或其它事故,那么將丟失整個數據集合,因為在將數據讀入 DRAM 后就擦除了閃存扇區。JFFS 附加文件而不是重寫整個扇區,并且具有崩潰/掉電安全保護這一功能。
3 這可能是最重要的一點:JFFS 是專門為象閃存芯片那樣的嵌入式設備創建的,所以它的整個設計提供了更好的閃存管理。
要構建JFFS文件系統,首先要有硬件設備FLASH及支持JFFS文件系統的操作系統。
摘要:本文主要分析了uclinux 2.4內核的jffs文件系統機制。希望能對基于uclinux開發產品的廣大工程師有所幫助。
關鍵詞:uclinux vfs jffs
申明:這份文檔是按照自由軟件開放源代碼的精神發布的,任何人可以免費獲得、使用和重新發布,但是你沒有限制別人重新發布你發布內容的權利。發布本文的目的是希望它能對讀者有用,但沒有任何擔保,甚至沒有適合特定目的的隱含的擔保。更詳細的情況請參閱 GNU 通用公共許可證(GPL),以及GNU 自由文檔協議(GFDL)。
你應該已經和文檔一起收到一份GNU 通用公共許可證(GPL)的副本。如果還沒有,寫信給:
The Free Software Foundation, Inc., 675 Mass Ave, Cambridge,MA02139, USA
歡迎各位指出文檔中的錯誤與疑問
一、flash讀寫的特殊性
對于嵌入式系統,flash是很常見的一種設備,而大部分的嵌入式系統都是把文件系統建立在flash之上,由于對flash操作的特殊性,使得在flash上的文件系統和普通磁盤上的文件系統有很大的差別,對flash操作的特殊性包括:
(1) 不能對單個字節進行擦除,最小的擦寫單位是一個block,有時候也稱為一個扇區。典型的一個block的大小是64k。不同的flash會有不同,具體參考flash芯片的規范。
(2) 寫操作只能對一個原來是空(也就是該地址的內容是全f)的位置操作,如果該位置非空,寫操作不起作用,也就是說如果要改寫一個原來已經有內容的空間,只能是讀出該sector到ram,在ram中改寫,然后寫整個sector。
由于這些特殊寫,所以在flash這樣的設備上建立文件也有自己獨特的特點,下面我們就以jffs為例進行分析。
二、jffs體系結構介紹
1、存儲結構
在jffs中,所有的文件和目錄是一樣對待的,都是用一個jffs_raw_inode來表示
整個flash上就是由一個一個的raw inode排列組成,一個目錄只有一個raw inode,對于文件則是由一個或多個raw inode組成。
2、文件組成
在文件系統mount到flash設備上的時候,會掃描flash,從而根據flash上的所有屬于一個文件的raw inode建立一個jffs_file結構以及node list。
下面的圖顯示了一個文件的組成
一個文件是由若干個jffs_node組成,每一個jffs_node是根據flash上得jffs_raw_inode而建立的,jffs_file主要維護兩個鏈表
版本鏈表:主要是描述該node創建的早晚,就是說version_head指向的是一個最老的node,也就意味著垃圾回收的時候最該回收的就是這個最老的node。
區域鏈表:這個鏈表主要是為讀寫文件創建的,version_head指向的node代表的文件數據區域是0~~~n-1 之后依次的節點分別是 n~~~m-1 m~~~~o-1 ……。其中n《M《=“” p=“” /》
3、操作
對文件的讀操作應該是比較簡單,但是寫操作,包括更改文件名等操作都是引起一個新的jffs_node的誕生,同時要寫一個相映的raw inode到flash上,這樣的操作有可能導致前面的某個jffs_node上面的數據完全失效,從而導致對應flash上的raw inode的空間成為dirty。
下面舉一個例子可能會更清楚一些。
一個文件的range list是由上面的三個jffs_node組成,當我們做如下寫操作的時候
lseek( fd, 10, SEEK_SET );
write( fd, buf,40 );
第一個和最后一個node被截短了,第二個node完全被新數據替換,該node會從鏈表上摘下來,flash上空間變成dirty。如果做如下寫操作的時候
lseek( fd, 23, SEEK_SET );
write( fd, buf,5 );
此時,第二個node被分裂成兩個node,同時產生一個新的node,range鏈表的元素變成五個。
評論
查看更多