項目組在無線環境下實現了Ubuntu12.04和Android4.0系統在Pandaboard ES開發板上的無線加載、啟動及切換。啟動過程中操作系統內核uImage和臨時根文件系統uInitrd通過wifi網絡加載到SD卡中,SD卡中只有輕量級的操作系統引導程序及我們特制的meta OS,系統實際的根文件系統rootfs存儲于遠程的服務器上,我們使用NFS協議在無線環境下掛載實際的根文件系統完成系統的啟動。目前,國內無線多操作系統引導技術文檔資料較少,支持多操作系統啟動的手機主要有兩款:一個是西班牙手機廠商Geeksphone開發的一款代號為Revolution的手機,另外一個是谷歌發布的Nexus系列。在這分享無線多操作系統啟動過程中通過NFS協議掛載遠程服務器上實際文件系統的一些經驗,一種可行的技術手段。目前是在局域網環境,性能有限,僅供大家參考。想分三部分來講。
(1)操作系統引導程序Boot Loader的改造;
(2)系統鏡像文件uImage的改造;
(3)系統啟動過程中uInitrd階段NFS掛載相關問題。
本文主要講解uInitrd階段NFS掛載相關問題,以Ubuntu12.04系統為例進行說明,Android系統先留著。
附上demo圖一張:
NFS,即Network File System網絡文件系統協議。NFS協議可以透過網絡,讓不同的機器、不同的操作系統彼此分享文件。它與Windows系統中的文件資源共享類似,不同的是NFS是在UNIX/Linux系統下實現的。NFS協議是通過網絡將用戶遠程服務器上的數據掛載到本地目錄,從而實現遠程數據本地透明獲取與訪問的一種方式。NFS服務器與客戶端掛載示意圖如下圖所示:
服務器將目錄/home/gsm/ubuntu
設為共享目錄,其他的客戶端主機可以將該共享目錄掛在指定的某個目錄下。掛載成功后,就可以在掛載目錄下看到與/home/gsm/ubuntu
完全一樣的子目錄和文件。
要完成uInitrd階段NFS的掛載,首先了解Linux系統的啟動流程。
(1)硬件加電自檢、初始化;
(2)讀取配置文件并執行操作系統引導程序Boot Loader;
(3)讀取Boot Loader的參數配置文件boot.scr,將內核uImage加載到內存中執行,uImage開始檢測硬件與加載驅動程序;
(4)uImage執行完成后,uInitrd加載到內存中執行,uInitrd解壓調用init腳本。注:uInitrd是Linux系統啟動過程中使用的臨時根文件系統,在Linux啟動之前,Boot Loader會將它加載到內存中,內核啟動的時候會將這個文件解開作為根文件系統使用;
(5)init腳本創建相應的文件目錄,掛載到相應的文件系統。最后完成交權,切換到系統實際的文件系統。
由Linux系統的啟動流程可知要實現智能移動終端通過無線網絡將操作系統內核鏡像文件uImage和臨時根文件系統uInitrd加載到終端上執行,并在uInitrd階段通過NFS協議掛載服務器上的實際根文件系統rootfs,完成系統交權、啟動。首先要完成的是Boot Loader的改造(這里略過不講),Boot Loader讀取配置文件將對應系統的uImage和uInitrd加載到內存中執行。然后,需要對系統內核uImage進行改造(略過不講),最后需要對uInitrd進行改造(也就是本文重點要介紹的)。
主要包括三方面:
(1)uInitrd無線模塊的添加;
(2)uInitrd啟動階段init腳本的修改;
(3)NFS掛載腳本以及無線配置函數等相關函數的定義。
Init腳本中有這么幾行代碼:
maybe_break mount
log_begin_msg "Mounting root file system..."
. /scripts/${BOOT}
parse_numeric ${ROOT}
mountroot
Linux系統本地啟動時,/scripts/${BOOT}中的BOOT參數默認為local,所以當系統改為NFS掛載遠程文件系統啟動時,BOOT參數要改為nfs。將/scripts/local 改為/scripts/nfs,即本地啟動改為NFS掛載啟動。
Init腳本中添加wifi配置函數wifi_networking,函數在/scripts/functions文件中定義。
wifi_networking()
{
wpa_supplicant -B -iwlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
ifconfig wlan0 192.168.1.99 netmask 255.255.255.0
route add default gw 192.168.1.1
}
修改scripts目錄下nfs文件,指定nfsmount目錄,設定掛載參數
在etc/wpa_supplicant/wpa_supplicant.conf中設定wifi參數
rootfs中配置無線參數;
當執行到init腳本最后一行代碼時run-init ${rootmnt} ${init},系統的啟動交給將要進入的系統的${init},并輸出,完成系統的交權,這里我們將run-init修改為/sbin/init。
目前制約性能的一些主要因素。在啟動過程中通過wireshark抓包分析可以知道,當終端與服務器的連接出現問題的時候,比如無線網絡突然出現問題的時候,終端將不斷地嘗試與服務器重新建立連接直到與服務器的連接恢復正常。在每次嘗試重連不成功后,連接的時間間隔將成指數級增長。(這里我們使用的NFS協議版本為V3,使用的傳輸協議為TCP/IP協議)
除此之外,在無線網絡環境下,數據塊丟包是經常出現的,如果出現了一個丟包,這丟失的數據塊會被重傳。無線網絡的不穩定性增加了數據塊丟失率。在這段期間,NFS客戶端將不斷地向NFS服務器請求重傳丟失的塊直至客戶端成功收到丟失的塊。(以太網有最大傳輸單元MTU的限制,為1500字節,所以數據傳輸過程會進行分塊)
對NFS協議有一定研究的歡迎交流,包括NFS協議改進,并發環境以及NFS讀寫塊大小,傳輸協議使用等參數設置問題。了解pNFS協議的求指導。