在目標機上可以運行uClinux了,接著就需要開發(fā)完成特定任務的應用程序了,。由于嵌入式uClinux的特殊開發(fā)環(huán)境(主機——目標機),其應用程序的開發(fā)模式也有多種,。
一種是在主機上編寫程序,然后編譯,、連接,、調(diào)試,成功后將程序和內(nèi)核一同編譯并下載到目標板,。這種模式中不利于開發(fā)的問題有:主機和目標機的運行環(huán)境(如指令集,,函數(shù)庫等)不同。另一種是通過網(wǎng)線或串口線將目標機和主機連起來,,直接在目標機上開發(fā)調(diào)試,。這種模式使用NFS將主機的特定目錄mount到目標機上,對主機的操作就是對目標機的操作,。采用 NFS模式可以方便應用程序的開發(fā),,減少映像文件的下載次數(shù)和對flash的燒寫次數(shù)。這對于縮短開發(fā)周期,,提高開發(fā)效率,,加快產(chǎn)品的上市時間相當重要。
1 NFS的簡要介紹
NFS是Network File System(網(wǎng)絡文件系統(tǒng))的縮寫,,最初是由Sun公司開發(fā)出來的分布式文件系統(tǒng),。提供NFS服務的一方是NFS Server(遠程主機),使用NFS服務的一方是NFS Client(客戶機),。利用它,,客戶機可以將遠程主機提供的共享目錄掛載到自己的目錄上,在本地的操作如同對遠程主機的操作,。
NFS有自己的協(xié)議與端口號(2049),,它本身并沒有提供傳輸資料的協(xié)議,但是NFS卻能通過網(wǎng)絡進行資料的共享,。這是因為在資料傳送或者其它相關(guān)數(shù)據(jù)交互的時候,,NFS用遠程過程調(diào)用(Remote Procedure Call, RPC)的傳輸協(xié)議,。RPC服務portmap負責管理服務與相關(guān)端口映射的工作,。因此,使用NFS服務必須先激活RPC服務portmap,,在主機和目標機上都要實現(xiàn)RPC服務,,才可以使用NFS。
使用NFS Server還需要激活至少兩個系統(tǒng)守護進程:rpc.nfsd用于管理Client使用主機共享目錄的權(quán)限,,包含對Client的IP的判別; rpc.mountd用于管理NFS的文件系統(tǒng),。當Client通過rpc.nfsd后,在使用NFS Server提供的文件前,還必須取得使用權(quán)限的認證,。rpc.nfsd及rpc.mountd的系統(tǒng)服務是由nfs-utils提供的,。
2配置主機和目標機的NFS服務
嵌入式系統(tǒng)的開發(fā)是基于主機/目標機,在主機上要安裝目標機的交叉編譯工具,。需要在主機上編譯出可以在目標機上運行的可執(zhí)行文件,。該可執(zhí)行文件通常需要下在到目標機上才可以運行,而利用NFS可以不用下載即可運行,。下面以主機RedHat9.0+PC,,IP為192.168.111.8;目標機 uCLinux(內(nèi)核為linux.2.4.x)+S3C44B0,IP為192.168.111.1的環(huán)境講解使用NFS需要的配置,。
2.1主機上的配置
NFS服務需要內(nèi)核(Kernel)支持,,因此,內(nèi)核版本最好高于2.2.x,。如果重新編譯內(nèi)核,,一定要選擇支持NFS。主機上的配置均以root用戶進行,。
2.1.1確認是否安裝了NFS服務
NFS服務一般在RedHat9.0安裝時就默認安裝的,。檢查是否安裝了nfs的方法是:
(1)查看/etc/rc.d/init.d目錄下是否有nfs和nfslock文件,如果有說明主機已經(jīng)安裝了nfs服務,。(#ls /etc/rc.d/init.d/)
(2)#rpm -qa| grep -i nfs,,出現(xiàn)redhat-config-nfs-1.0.4-5,
nfs-utils-1.0.1-2.9這表示安裝了NFS。如果沒有安裝,,安裝過程如下:
#mount /dev/cdrom /mnt/cdrom(掛載光盤)
#cd /mnt/cdrom/RedHat/RPMS
#rpm -ivh nfs-utils-1.0.1-2.9.i386.rpm rpm2.1.2檢查RPC程序是否已經(jīng)啟動
#rpcinfo –p,,檢查系統(tǒng)RPC運行狀況,若出現(xiàn)
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper 表示已經(jīng)啟動RPC程序,。
2.1.3啟動主機上的NFS服務,,并關(guān)閉防火墻
NFS服務一般不會在開機時自動啟用。啟動該服務:
(1)#ntsysv,,選中nfs,,nfslock和portmap;或者#setup,選擇System services里的nfs,,nfslock和portmap,。
(2)啟用portmap服務,# /etc/rc.d/init.d/portmap start。也可以#service nfs start 和#service portmap start啟動服務,。激活portmap后,,就會出現(xiàn)一個端口號為111的rpc服務。至于nfs則會激活至少兩個以上的系統(tǒng)守護進程,,然后就開始監(jiān)聽 Client的請求,,用#cat /var/log/messages可以看到以上操作是否成功,。
由于防火墻會關(guān)閉NFS服務(2049端口號)的對外服務,所以必須關(guān)閉防火墻,。在RedHat9.0上運行setup,,選擇Firewall configuration,選中No firewall,。然后到上一層菜單選擇System services,,去掉ipchains 和iptables 兩項服務。
2.1.4設置共享目錄
在文件/etc/exports中設定允許被訪問的共享目錄以及訪問的權(quán)限,。該文件的格式:/共享目錄 主機名稱或IP(權(quán)限參數(shù)),。修改此文件添加共享目錄(該目錄要存在),/home/pub *() //允許所有主機訪問此目錄,,權(quán)限為rw.
/home/nfs 192.168.111.8(rw) //允許IP為192.168.111.8的主機訪問此目錄,。權(quán)限為讀寫。
權(quán)限參數(shù)設定為:
rw:讀寫權(quán)限 ro:只讀權(quán)限
no_root_squash:如果是root使用共享目錄,,對于此目錄,,他就具有root的權(quán)限
root_squash:如果是root使用共享目錄,那么他的權(quán)限將被壓縮為匿名者(nobody)
all_squash:不論NFS的使用者身份如何,,他都會被壓縮成為匿名使用者(nobody)
anonuid:前面的匿名使用者的UID設定值,,通常為nobody;也可自行設定UID的值。(這個UID必需要存在于/etc/passwd中)
anongid:同anonuid,,但是變成groupID就是了
sync:資料同步寫入到內(nèi)存與硬盤中
async:資料會先暫存于內(nèi)存當中,,而不會直接寫入硬盤
2.1.5使/etc/exports文件生效,導出共享目錄
修改了/etc/exports文件后,,不需要重新激活nfs,,只需要重掃描/etc/exports的文件,將設定重新加載即可,,所使用的命令格式為#exportfs [-aruv],。其參數(shù)說明:
-a 全部掛載(或卸載) /etc/exports 文件中的設定
-r重新掛載/etc/exports里的設定,此外也更新/etc/exports及/var/lib/nfs/xtab
-u 卸載所掛目錄
-v將共享的目錄的情況顯示到屏幕上
這里,,輸入#exportfs –rv,,會將/etc/exports中所設置的共享目錄輸出。
exporting 192.168.111.8:/home/nfs
exporting *:/home/pub
reexporting 192.168.111.8:/home/nfs to kernel
每次修改了/etc/exports文件后都需要運行一次該命令,。
2.1.6檢查主機配置是否正確
(1)檢驗所共享的目錄內(nèi)容,,可以查看/var/lib/nfs/xtab這個文件:
# cat /var/lib/nfs/xtab 顯示共享出去的目錄信息。也可以用#showmount–e 192.168.111.1顯示主機上的共享目錄.
(2)觀察NFS激活的端口號,,# netstat –utln顯示內(nèi)容中有
udp 0 0 0.0.0.0:2049 0.0.0.0:*
這里2049是nfs服務所開啟的端口,,其它的端口是RPC Server其它程序隨機產(chǎn)生的,每次restart nfs都會得到不一樣的端口號,。
(3)mount自己提供的共享目錄,。#mount –t nfs 192.168.111.1:/home/pub /mnt/nfs,將主機/home/pub掛載到/mnt/nfs目錄下,。如果 mount成功,,表示主機配置正確。#cd /mnt/nfs,,#ls 看見的內(nèi)容就是/home/pub下的內(nèi)容,。
2.1.7卸載共享目錄,停止NFS服務
卸載共享目錄#umount /mnt/nfs(#umount /home/nfs)
停止(啟動)portmap服務 # /etc/rc.d/init.d/portmap stop(restart)
停止(啟動)nfs服務 #/etc/rc.d/init.d/nfs stop(restart)
2.2目標機上的配置
目標機為內(nèi)核為ARM7TDMI的S3C44BO板,運行uClinux操作系統(tǒng),。在目標機端使用NFS掛載主機上的共享目錄,,需要配置內(nèi)核和相應的用戶程序(make menuconfig)。2.2.1配置內(nèi)核
Networking options --> (缺省) //開啟網(wǎng)絡功能
Network device support --> (缺省)
File systems ->Network File Systems——〉 //支持NFS文件系統(tǒng)
<*> NFS file system support
# Provide NFSv3 client support
2.2.2用戶程序配置
Network Applications -->
# portmap
BusyBox -->
# mount(mount nfs support)(mount/unmount 命令有兩個地方可以選擇,,F(xiàn)ilesystem Applications 或BusyBox,。這里推薦選擇BusyBox。
配置完畢后,,將編譯生成的映像文件image.rom下載到目標機上flash中,。
3 基于NFS的應用程序開發(fā)
3.1在主機上編譯程序,并生成在目標機上運行的程序
在主機/home/pub下編輯hi.c,其內(nèi)容:
#include
main(){printf(“hi! Good!n”);}
交叉編譯hi.c,,#arm-elf-gcc –Wall –Wl,,-elf2flt –o hi hi.c生成flt格式的可執(zhí)行文件hi。修改hi的權(quán)限#chmod 711 hi,。該文件可以直接下載到目標機上運行,,這里利用NFS看其執(zhí)行情況。
3.2目標機利用NFS掛載主機并進行調(diào)試
用串口線將主機的COM1和目標機的COM0連接起來,,同時接上網(wǎng)線,。在主機上打開minicom(設置參數(shù):57600 8N1,無流控)用于同目標機通訊。目標機上電或者復位,,開始啟動uClinux,,顯示信息成功后進入sh。
在目標機上建立/var/nfs用于掛載主機上的目錄(這里采用的是romfs只讀文件系統(tǒng),,/var使用的是RAM disk驅(qū)動的ext2文件系統(tǒng),。所以僅/var可以用于讀寫,其它目錄只可以讀)# mkdir /var/nfs
啟動目標機上portmap服務 # portmap &
掛載主機上的共享目錄#mount -t nfs 192.168.111.1:/home/pub /var/nfs
#ls /var/nfs可以看到主機上/home/pub的文件,。此時,,可以運行該目錄下的可執(zhí)行程序hi,#./hi(注意要加“./”)出現(xiàn)hi! Good!,。程序正常運行,,將其編譯到內(nèi)核里。將hi拷貝到uClinux源碼包的/romfs/bin下編譯,,生成的image.rom可以下載到 flash,。在板子上的/bin下就有hi程序了,,并且可以直接執(zhí)行hi。
卸載使用umount # umount /var/nfs,。如果讓目標機啟動時自動運行portmap服務,,可以修改rc文件(uClinux源碼中),在最后加入/bin/portmap&,,mkdir /var/nfs,。
4 小結(jié)
使用NFS開發(fā)模式,關(guān)鍵在于對主機和目標機的配置,。如果配置不當,,就會mount失敗。以下是值得注意的地方:
mount成功,,可是運行程序. /hi時報告錯誤:Permission denied.即主機拒絕操作,。需要修改主機上程序的權(quán)限chmod 777 /home/pub/hi。然后在目標機端運行./hi即可,。
主機上設置時候一定要關(guān)閉防火墻,,不然目標機mount的時候沒有響應。
目標機上一定要先開啟portmap服務,。
主機和板子的IP在同一個網(wǎng)段,。
如果要運行大的應用程序,在Mount的時候最好加上:
-o rsize=1024,wsize=1024,timeo=15的參數(shù),,否則多半會得到server not responsing的提示信息,。