無線多作業系統啟動之uInitrd階段NFS掛載篇

wyzsk發表於2020-08-19
作者: Focusstart · 2014/06/06 14:23

0x00 背景


專案組在無線環境下實現了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圖一張:

enter image description here

0x01 NFS概述


NFS,即Network File System網路檔案系統協議。NFS協議可以透過網路,讓不同的機器、不同的作業系統彼此分享檔案。它與Windows系統中的檔案資源共享類似,不同的是NFS是在UNIX/Linux系統下實現的。NFS協議是透過網路將使用者遠端伺服器上的資料掛載到本地目錄,從而實現遠端資料本地透明獲取與訪問的一種方式。NFS伺服器與客戶端掛載示意圖如下圖所示:

enter image description here

伺服器將目錄/home/gsm/ubuntu設為共享目錄,其他的客戶端主機可以將該共享目錄掛在指定的某個目錄下。掛載成功後,就可以在掛載目錄下看到與/home/gsm/ubuntu完全一樣的子目錄和檔案。

要完成uInitrd階段NFS的掛載,首先了解Linux系統的啟動流程。

0x02 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掛載指令碼以及無線配置函式等相關函式的定義。

0x03 NFS無線掛載實現


Step 1:

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掛載啟動。

Step 2:

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
}

Step 3:

修改scripts目錄下nfs檔案,指定nfsmount目錄,設定掛載引數

Step 4:

在etc/wpa_supplicant/wpa_supplicant.conf中設定wifi引數

Step 5:

rootfs中配置無線引數;

Step 6:

當執行到init指令碼最後一行程式碼時run-init ${rootmnt} ${init},系統的啟動交給將要進入的系統的${init},並輸出,完成系統的交權,這裡我們將run-init修改為/sbin/init。

0x04 NFS協議分析


目前制約效能的一些主要因素。在啟動過程中透過wireshark抓包分析可以知道,當終端與伺服器的連線出現問題的時候,比如無線網路突然出現問題的時候,終端將不斷地嘗試與伺服器重新建立連線直到與伺服器的連線恢復正常。在每次嘗試重連不成功後,連線的時間間隔將成指數級增長。(這裡我們使用的NFS協議版本為V3,使用的傳輸協議為TCP/IP協議)

enter image description here

除此之外,在無線網路環境下,資料塊丟包是經常出現的,如果出現了一個丟包,這丟失的資料塊會被重傳。無線網路的不穩定性增加了資料塊丟失率。在這段期間,NFS客戶端將不斷地向NFS伺服器請求重傳丟失的塊直至客戶端成功收到丟失的塊。(乙太網有最大傳輸單元MTU的限制,為1500位元組,所以資料傳輸過程會進行分塊)

enter image description here

enter image description here

對NFS協議有一定研究的歡迎交流,包括NFS協議改進,併發環境以及NFS讀寫塊大小,傳輸協議使用等引數設定問題。瞭解pNFS協議的求指導。

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章