謝逸軒,馬維華
(南京航空航天大學 計算機科學與技術學院,江蘇 南京 211100)
科技發(fā)展日新月異,32位通用型MCU價格一次次下探以及5G萬物互聯(lián)的趨勢面前,開源穩(wěn)定帶網絡功能的Linux操作系統(tǒng)將會被移植到各個垂直領域,更新替換掉老舊的嵌入式設備。為了更好地服務于社會,系統(tǒng)掌握Linux移植這門技術需要在硬件資源性能溢出的當下搭建起便捷高效的開發(fā)調試平臺。NFS,全稱Network File System,是Linux系統(tǒng)中常用的一種文件共享服務,有著與Windows中服務器信息塊(Server Message Block,SMB)網絡文件共享服務一樣的便捷和用戶無感知的使用體驗[1]。如今,NFS已經從1984年的1.0發(fā)展到如今的4.2版本。
平臺由運行windows的筆記本、筆記本上虛擬出的Linux宿主機以及開發(fā)板三者構成。路由器接入互聯(lián)網,對內運行NAT和DHCP服務,設路由器的IP地址為192.168.1.1,子網掩碼24位。開發(fā)板使用網線接入路由器,筆記本既可無線也可有線接入,虛擬機的網絡適配器配置為橋接自動。配置路由器依據(jù)網卡MAC地址為開發(fā)板、筆記本、虛擬機各分配靜態(tài)IP地址,如圖1所示。開發(fā)板已經燒錄好帶NFS客戶端的U-boot,并與筆記本進行串口連接,以便鍵入命令控制和監(jiān)控Linux啟動和根文件系統(tǒng)掛載過程。筆記本和虛擬機上分別架設NFS服務,以方便數(shù)據(jù)傳輸,且由于其自帶網絡防火墻,需要注意關閉防火墻或添加端口白名單。
圖1 開發(fā)調試平臺網絡拓撲結構
下載并安裝haneWIN NFS Server for Windows[2]軟件服務包。
打開程序后(免安裝版需用管理員權限打開),依次進入Edit-Preferences-Exports-Edit exports file來設置需要共享的文件夾,配置文件格式為:共享目錄路徑+-name:共享目錄別名,每一行一個共享目錄。筆者以桌面上存放bootloader和內核的boot目錄,以及存放根文件系統(tǒng)的rootfs目錄為例,在對話框中添加以下內容并點擊Save保存配置。
C:UsersyournameDesktopoot-name:boot
C:UsersyournameDesktop ootfs-name:rootfs
此時,注意勾選“Map client root (UID 0) to root for all entries”選項,該選項可讓開發(fā)板內核以root權限掛載共享目錄。
在Linux虛擬機的終端中輸入mount-t nfs-o nolock 192.168.1.6:/boot /mnt,可查看是否掛載成功。若報錯或未成功掛載,檢查Windows防火墻是否將NFS Server程序加入了白名單或者防火墻是否已經關閉,-nolock選項意為當文件被寫入時,不使用額外的Network Lock Manager服務來鎖定該文件,添加此選項有助于增加兼容性。
成功驗證后,使用“umount /mnt”命令解除掛載。
2.2.1 CentOS 7用戶(默認root登錄,否則下述各命令前加入sudo)
使用以下命令安裝NFS服務包:
yum install -y nfs-utils rpcbind
編輯/etc/exports文件,配置需共享的目錄,配置格式:
共享目錄路徑+被允許掛載的主機/IP+(常用共享選項見表1,多選項間逗號分隔)。
現(xiàn)在以共享/root/boot和/root/rootfs為例,添加以下兩行到/etc/exports文件尾部:
/root/boot *(rw,insecure,async,no_root_squash,no_subtree_check)
/root/rootfs *(rw,insecure,sync,no_root_squash,no_subtree_check)
注:*表示任意主機;*與(之間不能存在空格。
更改NFS服務器選項以兼容U-boot上的NFS V2版本,Linux上的NFS服務器默認不兼容V2版本,編輯/etc/nfs.conf文件,分別找到[nfsd]和vers2=y兩行,刪除兩行前各自的#號以取消注釋。如果沒找到可以直接添加這兩行內容,保存并退出。
重啟NFS服務以生效上述配置,在終端中輸入:
systemctl restart nfs
為NFS服務添加防火墻白名單或者使用以下命令暫時關閉防火墻(重啟后失效):
systemctl stop firewalld
使用mount -t nfs -o nolock 192.168.1.8:/root/boot /mnt或者showmount -e 192.168.1.8來驗證共享配置的生效。使用cat /proc/fs/nfsd/versions來驗證服務器兼容版本中是否包含+2(NFS Version 2)。
如果需要NFS服務開機自啟并禁用防火墻,輸入
systemctl enable nfs
systemctl disable firewalld
2.2.2 Ubuntu 20.04用戶(默認普通用戶登錄)
使用以下命令安裝NFS服務包:
sudo apt install nfs-kernel-server
編輯/etc/exports文件,配置格式與示例與CentOS 7用戶一致,請參照上節(jié)完成共享目錄配置。
編輯/etc/default/nfs-kernel-server文件,以兼容U-boot上的NFS V2的版本,Linux上的NFS服務器默認不兼容V2版本。找到RPCNFSDCOUNT、RPCMOUNTDOPTS兩項,分別將其修改為以下內容,其余不變:
RPCNFSDCOUNT=”—nfs-version 2 8”
RPCMOUNTDOPTS=”—nfs-version 2—manage-gids”
重啟NFS服務以生效上述配置,在終端中輸入:
sudo systemctl restart nfs-kernel-server
由于ubuntu系統(tǒng)默認關閉防火墻,故不需要額外操作。確需關閉的,請運行sudo ufw disable。
使用sudo mount -t nfs -o nolock 192.168.1.8:/root/boot /mnt或者sudo showmount -e 192.168.1.8來驗證共享配置的生效。使用sudo cat /proc/fs/nfsd/versions來驗證服務器兼容版本中是否包含+2(NFS Version 2)。
Ubuntu系統(tǒng)上的NFS服務默認自啟動,無需額外配置。
表1 NFS服務端共享選項[3]
2.2.3 開發(fā)板使用NFS啟動Linux內核并掛載遠端根文件系統(tǒng)
為開發(fā)板斷電再上電;在putty(串口終端程序名)中鍵入任意鍵打斷開發(fā)板普通啟動過程;鍵入以下命令,以使用NFS啟動Linux內核并掛載遠端根文件系統(tǒng)(以Windows為例):
setenv serverip 192.168.1.6→#啟用Windows上的NFS服務IP地址
setenv ipaddr 192.168.1.4→#為開發(fā)板自身設定同子網下的IP地址
setenv rootpath /rootfs→#Windows上設置的根文件系統(tǒng)別名
setenv bootpath /boot→#Windows上設置的啟動文件夾目錄別名
setenv fdtfile am335x.dtb→#指示開發(fā)板自身設備樹的文件名
setenv fdtaddr 0x88000000→#指示設備樹在內存中的位置
setenv bootfile zImage→#指示Linux內核文件名
setenv loadaddr 0x82000000→#指示Linux內核在內存中的位置
setenv nfsloadimage “nfs ${loadaddr} ${serverip}:${bootpath}/${bootfile}”
#指示U-boot從NFS服務器上下載Linux內核到內存指定位置
setenv nfsloadfdt “nfs ${fdtaddr} ${serverip}:${bootpath}/${fdtfile}”
#指示U-boot從NFS服務器上下載設備樹文件到指定內存位置
setenv nfsargs “setenv bootargs console=ttyO0,115200n8 root=/dev/nfs nfsroot=${serverip}:${rootpath},nolock rw ip=dhcp”
#設置內核啟動參數(shù),將內核console設置為串口ttyO0并以波特率115200bps、無奇偶校驗、8位數(shù)據(jù)位的規(guī)格通信,通知內核通過NFS掛載根文件系統(tǒng)。
setenv nfsboot “setenv autoload no; run nfsloadimage; run nfsloadfdt; run nfsargs; bootz ${loadaddr}-${fdtaddr}”
#自定義NFS命令啟動腳本,以便重復使用
saveenv→#保存上述環(huán)境變量,以便重復使用
run nfsboot→#使用NFS啟動遠程內核并掛載遠程根文件系統(tǒng),下次重啟開發(fā)板時可直接運行最后這一條命令以快速啟動
總結之前,需注意上述方法的兩種常見誤區(qū):一是不能在Windows下解壓rootfs.tar.gz到根文件系統(tǒng)的共享目錄,但是可通過Linux虛擬機掛載Windows共享目錄后使用tar-xvf命令解壓導入,否則會產生此類報錯 [5.316458] Starting init: /sbin/init exists but couldn’t execute it (error-13)。二是當內核滾屏輸出[5.226074]bootserver=192.168.1.1, rootserver=192.168.1.6, rootpath= 時,不要因為rootpath= 后面為空就認為內核啟動參數(shù)傳入有誤,正常啟動的話rootpath=后也是空白的。
進行嵌入式Linux移植,不可避免使用Linux作為交叉編譯的宿主機,但是由于國人的電腦操作習慣仍舊是建立在Windows系統(tǒng)上的,那么采取Windows系統(tǒng)為主力查詢各種資料,虛擬機安裝Linux發(fā)行版為輔助編譯目標文件便是最自然的選擇。此時,采用本文所述的NFS文件系統(tǒng)穿插其中,起到橋梁作用,進一步為嵌入式Linux移植開發(fā)提供便利。