試環(huán)境搭建與優(yōu)化)
做嵌入式開發(fā)的人應該都經(jīng)歷過一種糾結(jié)明明可以抱著一塊開發(fā)板到處跑卻總得拖著一根網(wǎng)線才能干活。有的板子沒有有線網(wǎng)口有的板子放在某個現(xiàn)場角落拉線不現(xiàn)實還有些時候手里拿的是一臺手機改裝過的調(diào)試終端。這時候把NFS和TFTP這兩個調(diào)試利器架到WiFi上就成了非常現(xiàn)實的需求。這篇內(nèi)容我想把“WiFi模式下nfs與tftp的網(wǎng)絡環(huán)境搭建”這件事從頭到尾捋一遍。它不復雜但也不是直接把有線環(huán)境的配置搬過來就行——無線鏈路的延遲、丟包、IP漂移這些特性會實實在在影響NFS的掛載穩(wěn)定性和TFTP的傳輸成功率。這篇文章適合正在用開發(fā)板做根文件系統(tǒng)掛載調(diào)試的工程師適合想擺脫網(wǎng)線束縛的嵌入式愛好者也適合那些手里只有WiFi環(huán)境、卻要折騰uboot和內(nèi)核鏡像傳輸?shù)娜?。先給你交個底這套環(huán)境本身并不難難的是讓它穩(wěn)定、可復用。下面我會從整體設計思路說起把服務端配置、客戶端優(yōu)化、WiFi場景下的驗證和排錯一路講完。我不喜歡寫那種“復制粘貼就能跑”的教程你想跑起來很容易想跑得穩(wěn)就得知道參數(shù)背后的原因。1. WiFi模式下NFS與TFTP環(huán)境的整體設計與核心思路1.1 為什么非要在WiFi下搭這套環(huán)境先把場景掰開。NFSNetwork File System解決的是開發(fā)板啟動時掛載根文件系統(tǒng)的問題TFTP解決的是uboot階段傳輸內(nèi)核鏡像、設備樹文件的問題。這兩個服務在有線網(wǎng)絡下都非常成熟但WiFi場景會引入幾個有線環(huán)境幾乎不會遇到的不確定因素IP地址可能是動態(tài)分配的、丟包率比網(wǎng)線高一個數(shù)量級、延遲抖動明顯、路由器的AP隔離可能直接掐斷設備間的互訪。我碰到過的真實場景是某塊開發(fā)板自帶WiFi模塊但沒有以太網(wǎng)口項目現(xiàn)場又不能隨便布線。當時手頭只有一臺筆記本電腦和一個家用路由器要在這種條件里完成內(nèi)核下載、文件系統(tǒng)掛載的整套調(diào)試不像聽起來那么輕松。特別是第一次用TFTP傳內(nèi)核時反復超時后來發(fā)現(xiàn)是WiFi基站下的丟包率偏高小文件沒感覺一傳到十幾MB就原形畢露。WiFi天然具有“移動性”優(yōu)勢很多開發(fā)環(huán)境需要設備在實際擺放位置調(diào)試電腦可以就近放著但網(wǎng)線布不過去。把NFS和TFTP從有線遷到無線本質(zhì)上是把調(diào)試鏈路的傳輸介質(zhì)換掉了但服務架構(gòu)沒有變一臺開發(fā)機服務器提供共享目錄和啟動文件開發(fā)板作為客戶端啟動時通過網(wǎng)絡拉取資源。區(qū)別在于無線鏈路不允許你像有線那樣“隨便配配就能用”必須針對鏈路質(zhì)量做參數(shù)層面的適配。1.2 網(wǎng)絡拓撲與鏈路規(guī)劃這套環(huán)境里的角色劃分非常清晰開發(fā)機也被稱作宿主機安裝并運行NFS服務端和TFTP服務端通常通過網(wǎng)線或WiFi接入同一個局域網(wǎng)段。開發(fā)板客戶端通過WiFi接入相同局域網(wǎng)啟動過程中先從DHCP獲取IP或配置靜態(tài)IP然后依次通過TFTP下載內(nèi)核、通過NFS掛載根文件系統(tǒng)。無線模式下我強烈建議給開發(fā)板固定IP而不是完全依賴DHCP動態(tài)分配。原因后面細說簡單講就是動態(tài)IP在WiFi下重新關聯(lián)路由器時很容易變化而NFS掛載一旦斷掉再恢復就要重新定位服務器IP這會浪費大量調(diào)試時間。實測中比較穩(wěn)的搭配是路由器開啟DHCP靜態(tài)綁定把開發(fā)板的MAC地址和某個固定IP綁在一起。這樣既不用在板子上寫死IP換網(wǎng)絡環(huán)境時還能自動適配又能保證每次重新上電后IP不變。這是整套環(huán)境的鏈路示意圖路由器位于中間開發(fā)機通過WiFi/網(wǎng)線接入開發(fā)板通過WiFi接入兩者處于同一網(wǎng)段。TFTP走的是UDP 69端口NFS走的是TCP/UDP 2049端口外加一組動態(tài)端口rpcbind。WiFi環(huán)境下如果路由器開啟了AP隔離客戶端隔離這兩個設備的二層通信會被直接切斷表現(xiàn)為互相ping不通——這個問題我后文還會專門說。1.3 方案選型為什么不直接用U盤或串口你可能問既然WiFi不穩(wěn)定為什么不直接U盤拷貝、串口下載答案是效率和迭代速度。嵌入式調(diào)試是一個“改代碼、編內(nèi)核、拷過去、看現(xiàn)象”的循環(huán)串口傳一個大內(nèi)核要等幾分鐘U盤還得來回插拔。NFS和TFTP的價值在于把“傳輸”變成網(wǎng)絡上的常態(tài)操作每次改動后重啟開發(fā)板就能加載最新內(nèi)容。WiFi雖然不如有線穩(wěn)定但勝在沒有物理束縛尤其適合移動調(diào)試和現(xiàn)場聯(lián)調(diào)場景。這套方案解決的真實痛點其實就一句話在沒有有線條件的環(huán)境里保留完整的網(wǎng)絡調(diào)試能力。代價則是鏈路質(zhì)量下降所以整個配置過程不能照搬有線思路要在NFS協(xié)議版本、掛載超時參數(shù)、TFTP塊大小這些層面上做針對性調(diào)整。2. 服務端基礎環(huán)境搭建NFS與TFTP的安裝和啟動2.1 確認服務端網(wǎng)絡狀態(tài)與軟件源無論你用的是哪一套Linux發(fā)行版第一步都先確認開發(fā)機自身的網(wǎng)絡狀態(tài)。這一步看起來多余但確實現(xiàn)場翻車過很多回有人裝好了NFS掛載時才發(fā)現(xiàn)服務端自己有兩個IP開發(fā)板訪問的是那個被防火墻擋住的地址。# 查看網(wǎng)卡IP與連接狀態(tài) ip addr show ip route show # 確認能與開發(fā)板互通先做一次基本ping ping 開發(fā)板IP我建議第一次搭建的時候用有線把開發(fā)機和路由器連接起來確認整套NFSTFTP流程走通再切換到WiFi做鏈路優(yōu)化。這不是慫而是把變量拆開排查——有線都跑不通就上無線出了問題都不知道怪誰。軟件源方面Debian系和Red Hat系裝的服務名字不一樣但核心組件一樣發(fā)行版系NFS服務端包名TFTP服務端包名Debian/Ubuntunfs-kernel-servertftpd-hpaCentOS/RHEL/Rockynfs-utilstftp-server2.2 安裝NFS服務端以Debian系為例sudo apt update sudo apt install -y nfs-kernel-server裝完之后不要急著配先把服務狀態(tài)確認一下sudo systemctl status nfs-server這個服務名在Debian系上是 nfs-server在部分版本上可能是 nfs-kernel-server。不管叫啥state為activerunning就行。Red Hat系的安裝命令是sudo dnf install -y nfs-utils sudo systemctl enable --now nfs-server這一步的作用是讓NFS在開機后自動拉起避免每次手動啟動。后面你在開發(fā)板上配置開機自動掛載時服務端的自啟動就是前提條件。2.3 安裝TFTP服務端TFTP的陣營選擇比較多我用的是 tftpd-hpa理由是它配置集中、支持systemd管理、參數(shù)語義清楚。Debian系安裝sudo apt install -y tftpd-hpaRed Hat系則要裝 tftp-server并通過socket激活sudo dnf install -y tftp-server sudo systemctl enable --now tftp.socket注意Red Hat系會拆成tftp.service和tftp.socket兩個單元實際監(jiān)聽68/69端口的是socket單元部署的時候要確認socket是啟動狀態(tài)。我見過有人在Red Hat上配了老半天配置文件結(jié)果發(fā)現(xiàn)tftp.service是獨立的、根本不是自己用的那個進程。2.4 防火墻策略NFS和TFTP的端口開放防火墻是NFS環(huán)境搭建里翻車率最高的環(huán)節(jié)。NFS本身不止監(jiān)聽2049端口它依賴rpcbind動態(tài)分配端口所以不能只放行2049還要放行rpcbind的111端口以及一系列動態(tài)端口。TFTP則相對簡單固定UDP 69端口。Debian系的ufw可以這樣操作sudo ufw allow 2049/tcp sudo ufw allow 2049/udp sudo ufw allow 111/tcp sudo ufw allow 111/udp sudo ufw allow 69/udpRed Hat系的firewalld更省事直接認服務名sudo firewall-cmd --permanent --add-servicenfs sudo firewall-cmd --permanent --add-servicerpc-bind sudo firewall-cmd --permanent --add-servicetftp sudo firewall-cmd --reloadfirewalld能識別nfs這個服務名會自動放行2049、111以及NFS動態(tài)端口。但有一個問題有些環(huán)境中firewalld的服務定義不包含全部動態(tài)端口范圍配置完還是掛不上。保險起見可以查看自己的NFS實際使用了哪些端口rpcinfo -p | grep nfs如果發(fā)現(xiàn)動態(tài)端口不在防火墻放行范圍內(nèi)就得手動加一條規(guī)則。有種更穩(wěn)的做法是固定NFS動態(tài)端口范圍到某個區(qū)間再對區(qū)間放行具體做法是把下面這行寫進 /etc/nfs.conf 的[nfsd]段[nfsd] vers3y vers4y動態(tài)端口固定的做法稍復雜但在部分企業(yè)路由器環(huán)境下確實更可靠。這是后話如果你只是個人開發(fā)環(huán)境放行服務名的方案通常就夠了。3. NFS核心配置與WiFi鏈路下的參數(shù)優(yōu)化3.1 導出目錄配置/etc/exports 的每一項都別糊弄NFS服務端配置核心就一個文件/etc/exports。它定義了“哪些目錄可以給誰用、用什么權(quán)限”。我的習慣是單獨劃一個目錄做嵌入式調(diào)試共享區(qū)比如 /srv/nfs/rootfs里面放編譯好的根文件系統(tǒng)。一個典型的exports條目/srv/nfs/rootfs 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)四個參數(shù)里每個都有講究rw允許讀寫。調(diào)試階段你經(jīng)常要在開發(fā)板上寫文件只讀的話連日志都存不下來。sync服務端在響應客戶端寫請求前必須將數(shù)據(jù)落盤。WiFi下鏈路本來就不穩(wěn)sync能最大限度避免數(shù)據(jù)不一致的問題。有人為了性能用async但是在嵌入式調(diào)試場景我寧可慢一點也要數(shù)據(jù)安全。no_subtree_check關閉子目錄的權(quán)限檢查。這個參數(shù)能降低NFS在目錄重命名等場景下的延遲WiFi下尤其有價值。no_root_squash允許開發(fā)板上的root用戶以root權(quán)限訪問共享目錄。沒有這個參數(shù)開發(fā)板上的root會被映射成nobody你連創(chuàng)建設備節(jié)點都做不了很多根文件系統(tǒng)掛載后會直接啟動失敗。寫完exports后執(zhí)行sudo exportfs -ra sudo showmount -e localhostshowmount -e 輸出的內(nèi)容就是開發(fā)板側(cè)能看到的共享列表。如果這里沒有輸出你的共享目錄大概率是exports格式寫錯了別急著去客戶端排查。3.2 WiFi場景下NFS掛載參數(shù)的選擇邏輯服務端配置搞定后真正能體現(xiàn)“WiFi優(yōu)化”的是客戶端掛載參數(shù)。有線環(huán)境下很多人直接 mount -t nfs 192.168.1.10:/srv/nfs/rootfs /mnt/nfs但無線環(huán)境的丟包與延遲不允許這么粗暴。這是我實測在WiFi場景下很好用的一組參數(shù)mount -t nfs -o nolock,tcp,rsize4096,wsize4096,timeo50,retrans5,soft \ 192.168.1.10:/srv/nfs/rootfs /mnt/nfs逐項說明nolock關閉NFS的鎖管理。開發(fā)板側(cè)的NFS客戶端鎖機制在無線環(huán)境下容易觸發(fā)問題關閉后能減少掛載失敗的概率。tcp強制走TCP而非UDP。WiFi本身丟包率不低TCP的重傳機制能保證數(shù)據(jù)傳輸完整性。有人擔心TCP比UDP慢但在NFS場景下TCP的可靠優(yōu)勢遠大于那點延遲差。rsize/wsize4096單次讀寫的塊大小。有線環(huán)境你完全可以設成32768但WiFi下大塊傳輸容易觸發(fā)底層重傳風暴4096是實踐下來比較折中好用的值。timeo50超時時間單位是0.1秒也就是5秒。這個值比默認的60060秒小很多。為什么不直接用默認因為默認超時在無線鏈路上會讓你等很久才報錯調(diào)試時卡在那里非常被動。retrans5重傳次數(shù)。配合timeo約5次重試后還沒成功就報錯。這兩個參數(shù)的意義是把“等待掛載結(jié)果”的時長控制在可接受范圍內(nèi)。soft使用軟掛載即重試超時后返回錯誤而不是無限阻塞。開發(fā)調(diào)試階段用soft因為你經(jīng)常改配置、調(diào)鏈路硬掛載一旦斷連會卡死整個系統(tǒng)只能重啟開發(fā)板。我之前在某塊板子上測試過同樣的NFS共享有線掛載開機到進入shell大約10秒WiFi下用優(yōu)化參數(shù)大約14秒。多出的時間主要是無線鏈路的連接開銷和NFS握手延遲這個代價可以接受。但你如果用默認的全部參數(shù)直接掛會出現(xiàn)一種情況掛載命令執(zhí)行后沒有任何反饋卡幾分鐘都不報錯——那是硬掛載的等待重傳機制在空轉(zhuǎn)。3.3 客戶端掛載操作與開機自動掛載手動掛載確認無誤后最好把掛載動作固化到開發(fā)板的啟動流程里。有兩種常見做法一種是把掛載命令寫進啟動腳本rc.local或systemd服務另一種是寫進 /etc/fstab。開發(fā)板上的文件系統(tǒng)如果本身在本地Flash里fstab是合適的192.168.1.10:/srv/nfs/rootfs /mnt/nfs nfs nolock,tcp,rsize4096,wsize4096,timeo50,retrans5,soft 0 0如果開發(fā)板根本沒有本地根文件系統(tǒng)整個過程是“uboot通過TFTP下載內(nèi)核 - 內(nèi)核通過NFS掛載根文件系統(tǒng)”那掛載參數(shù)要傳在內(nèi)核bootargs里。比如root/dev/nfs nfsroot192.168.1.10:/srv/nfs/rootfs,tcp,nolock,rsize4096,wsize4096 rw ipdhcp注意這里的nfsroot參數(shù)列表和服務端配置是配套的。別小看這個細節(jié)我見過有人uboot能起來、TFTP也能下內(nèi)核但根文件系統(tǒng)一直掛不上最后發(fā)現(xiàn)是bootargs里沒寫tcp、nolock內(nèi)核默認用UDP掛載在WiFi下就是會莫名失敗。3.4 NFS權(quán)限問題的排查思路Permission denied是NFS最常見的錯誤之一而在WiFi環(huán)境中多了一層配IP的干擾讓問題更難定位。排查順序是先確認客戶端拿到的是否是192.168.1.0/24網(wǎng)段的IP再看exports里的網(wǎng)段是否覆蓋了這個IP再看no_root_squash是否加上了。小技巧在服務器端看日志能最快定位權(quán)限問題。sudo tail -f /var/log/syslog | grep nfs日志會直接告訴你“nfsd: permission error”以及來源IP。我看到過不少人折騰半天防火墻結(jié)果全是網(wǎng)段寫錯導致的權(quán)限拒絕。還有一個坑是SELinux。Red Hat系默認SELinux強制模式會攔NFS流量表現(xiàn)為客戶端卡在掛載、服務端日志卻干干凈凈。臨時驗證可以先執(zhí)行 setenforce 0如果掛載立刻成功說明就要么關SELinux要么打SELinux布爾值放行NFS。4. TFTP服務配置啟動文件的分發(fā)通道4.1 TFTP與NFS的職責邊界在整套啟動流程里TFTP和NFS的分工是uboot階段用TFTP下載內(nèi)核鏡像和設備樹因為uboot里的NFS客戶端太簡陋性能和穩(wěn)定性都差內(nèi)核接管啟動后再用NFS掛載根文件系統(tǒng)。這兩個服務各管一段但文件來源可以共享同一個目錄也可以分開。TFTP配置目錄建議放在 /srv/tftp 或者 /var/lib/tftpboot。里面放zImage、uImage、設備樹dtb文件。你可能會問這些文件都不大為什么WiFi下還偶爾傳失敗因為TFTP走UDP本身沒有擁塞控制WiFi的隨機丟包一旦觸發(fā)了服務端的超時重傳重傳往往也一起丟——這就是TFTP在無線環(huán)境里“越傳越慢、最后失敗”的根因。4.2 tftpd-hpa 的配置細節(jié)tftpd-hpa的配置文件在 /etc/default/tftpd-hpa內(nèi)容一般長這樣TFTP_USERNAMEtftp TFTP_DIRECTORY/srv/tftp TFTP_ADDRESS:69 TFTP_OPTIONS--secure --create每個配置項的作用TFTP_USERNAME運行tftpd的進程用戶建議專用低權(quán)限用戶tftp。防止TFTP被攻擊時拿到root權(quán)限。TFTP_DIRECTORYTFTP的根目錄。--secure模式下客戶端訪問的所有文件都限制在這個目錄里相當于chroot。TFTP_ADDRESS監(jiān)聽地址:69表示監(jiān)聽所有網(wǎng)卡的69端口。也可以指定開發(fā)機的IP比如192.168.1.10:69這樣更安全但如果開發(fā)機IP變化會直接失聯(lián)。TFTP_OPTIONS--secure是安全的chroot模式務必保留。--create允許客戶端創(chuàng)建文件這樣開發(fā)板也能把日志、臨時文件傳回服務端。如果只是為了啟動鏡像下載不一定要加--create。改完配置后sudo systemctl restart tftpd-hpa sudo ss -ulpn | grep :69看到監(jiān)聽在69端口就說明服務起來了。有些老教程會教你把TFTP托管給xinetd配置 /etc/xinetd.d/tftp。我不推薦新環(huán)境用xinetd因為它多了一層進程管理的復雜度systemd已經(jīng)把它替代得差不多了。用tftpd-hpa的獨立daemon模式啟動快、日志清晰、排查方便。4.3 WiFi鏈路下的TFTP實測驗證搭建完服務端用命令行tftp客戶端做一次完整測試# 開發(fā)機上測試 tftp 192.168.1.10 tftp put testfile.txt tftp get zImage tftp quit建議傳一個稍微大一點的文件幾十MB級別來驗證穩(wěn)定性。我第一次在WiFi下傳35MB的內(nèi)核壓縮包傳了三次兩次在校驗階段失敗都是丟包導致的。TFTP協(xié)議有個天然限制單塊數(shù)據(jù)固定512字節(jié)超時時間默認5秒。在無線鏈路下如果丟包率高于1%重傳會頻繁觸發(fā)整個傳輸過程會拖得很長甚至超時終止。我實測的一個實用優(yōu)化是按數(shù)據(jù)包模式調(diào)整雖然TFTP協(xié)議本身規(guī)定了超時重傳但客戶端uboot往往沒給你調(diào)節(jié)超時的選項。所以更現(xiàn)實的辦法是能用NFS就用NFSTFTP只傳小文件。如果必須傳大文件優(yōu)先考慮從服務端角度降低鏈路丟包率——換5GHz頻段、靠近路由器、減少無線信道干擾比在TFTP參數(shù)上做文章有效得多。4.4 與uboot結(jié)合的啟動流程如果你在uboot階段使用TFTP需要在uboot環(huán)境變量里指定服務端IP和文件名。大致流程如下setenv serverip 192.168.1.10 setenv ipaddr 192.168.1.20 setenv bootfile zImage # 下載內(nèi)核到內(nèi)存 tftp 0x81000000 ${bootfile} # 下載設備樹 tftp 0x82000000 ${devicetree}這里有一個經(jīng)常出錯的地方uboot的ipaddr、serverip必須和開發(fā)板運行內(nèi)核后使用的IP保持一致否則會出現(xiàn)“uboot下tftp成功內(nèi)核啟動后網(wǎng)絡不通”的詭異狀況。WiFi環(huán)境下尤其要注意如果路由器給開發(fā)板分配的是動態(tài)IPuboot階段的固定ipaddr和內(nèi)核階段的DHCP獲得的IP可能不一致導致服務器無法回包或者NFS掛載失敗。最省心的方案是前面說過的路由器上綁定開發(fā)板MAC到固定IP同時uboot里把ipaddr設成同一個固定IPserverip設為開發(fā)機IP。然后把內(nèi)核bootargs改成 ip192.168.1.20::192.168.1.1:255.255.255.0::wlan0:off用靜態(tài)IP而不是dhcp。這樣整條鏈路從uboot到內(nèi)核IP一致不容易出幺蛾子。5. WiFi環(huán)境下的聯(lián)通性驗證與穩(wěn)定性加固5.1 從物理層到應用層的逐級驗證很多人搭完環(huán)境掛載失敗第一反應就是改NFS參數(shù)實際上問題可能出在物理鏈路。無線環(huán)境下必須按這個順序排查每一步都通過再進下一步先在開發(fā)板上確認無線連接本身正常ip link show wlan0 iw dev wlan0 linkiw dev 的輸出能看到當前連接的SSID和信號強度。信號強度低于-70dBm就要小心了這個閾值下丟包率會劇增NFS和TFTP都會表現(xiàn)得不穩(wěn)定。然后驗證基本連通性ping -c 5 192.168.1.10不要只看“通不通”要關注延遲分布和丟包率。如果ping的丟包率超過1%后面的NFS、TFTP都不必談先解決鏈路問題。第三步驗證端口可達性# 開發(fā)板側(cè)測試NFS端口 nc -vz 192.168.1.10 2049 # 測試TFTP端口 nc -vzu 192.168.1.10 69nc測TCP端口穩(wěn)一點UDP端口測試不一定準確nc的UDP模式不保證能反映服務端狀態(tài)但好在TFTP服務是否啟動可以通過ss命令在服務端確認兩端對照即可。最后驗證NFS共享列表showmount -e 192.168.1.10如果能列出共享但掛載失敗問題基本鎖定在掛載參數(shù)或權(quán)限而不是鏈路。5.2 AP隔離WiFi下最容易被忽略的攔路虎很多家用路由器默認開啟“AP隔離”也叫客戶端隔離、無線隔離目的是防止同一WiFi下的設備互相訪問。這個功能對普通家庭上網(wǎng)沒影響但對嵌入式調(diào)試是致命的開發(fā)板和開發(fā)機都能上網(wǎng)、都能ping通路由器但彼此無法通信。癥狀是開發(fā)板ping開發(fā)機能通因為走的是路由器轉(zhuǎn)發(fā)AP隔離一般只隔離WLAN客戶端之間的二層直接通信不一定隔離三層轉(zhuǎn)發(fā)實際上多數(shù)家用路由的AP隔離會擋掉客戶端之間的所有訪問包括局域網(wǎng)內(nèi)訪問。我來說一個清晰的判斷方法如果開發(fā)板和開發(fā)機都能ping通路由器但互相ping不通第一優(yōu)先懷疑就是AP隔離。處理方式是登錄路由器后臺關閉“AP隔離”或“無線AP隔離”設置位置通常在無線設置的高級選項里。有的固件把guest network默認開啟并默認啟用隔離如果你連接的是訪客網(wǎng)絡大概率就是這個原因。5.3 頻段選擇與信號質(zhì)量優(yōu)化2.4GHz和5GHz在這個場景里我會毫不猶豫選5GHz。原因很直接2.4GHz頻段在家庭和辦公環(huán)境里干擾源太多藍牙、微波爐、USB 3.0設備、鄰居WiFi都在搶信道。實測在同一個位置2.4GHz下ping延遲的抖動范圍可以達到幾十毫秒5GHz則穩(wěn)定在個位毫秒級。如果你的開發(fā)板支持5GHz一定切到5GHz如果不支持就得在2.4GHz下做更多鏈路層面的補償比如把路由器擺放得更近、選擇一個不那么擁擠的信道。另外有個WiFi省電模式的坑。很多開發(fā)板的無線網(wǎng)卡默認開啟省電模式power save這會帶來明顯的延遲尖峰和偶發(fā)丟包。開發(fā)板連接WiFi后通過下面的命令關閉省電iw dev wlan0 set power_save off這條命令太實用了。我之前在某塊板子上遇到過NFS隨機卡死的情況查了一圈發(fā)現(xiàn)是無線網(wǎng)卡每隔幾秒進入一次休眠再喚醒TCP連接沒斷但是傳輸停頓了一下NFS客戶端就等超時了。關掉省電模式以后問題再沒出現(xiàn)過。5.4 動態(tài)IP場景下的掛載自恢復即使做了靜態(tài)綁定WiFi斷開重連后開發(fā)板的IP可能依然會變或者網(wǎng)絡棧在重連過程中出現(xiàn)短暫不可用。這時候NFS掛載會卡住或報錯。如果你沒有做靜態(tài)綁定那么在開發(fā)板上寫一個小的監(jiān)控腳本是必要的#!/bin/sh while true; do ip addr show wlan0 | grep 192.168.1.10 /dev/null 21 if [ $? -ne 0 ]; then IP_CHANGED1 fi mountpoint -q /mnt/nfs if [ $? -ne 0 ] [ $IP_CHANGED -eq 1 ]; then mount -t nfs -o nolock,tcp,rsize4096,wsize4096,timeo50,retrans5,soft \ 192.168.1.10:/srv/nfs/rootfs /mnt/nfs IP_CHANGED0 fi sleep 10 done這個腳本雖然是簡化版本但是思路是對的檢測IP、檢測掛載狀態(tài)、重新掛載。實際項目里你可以把它弄成一個systemd服務。有這個腳本兜底WiFi重啟、路由器重啟后調(diào)試環(huán)境能自動恢復省掉很多手動操作。6. 常見故障排查與個人實操心得先把這段時間積攢下來的高頻問題做成一個速查表遇到的問題基本都能在里面找到入口現(xiàn)象可能原因排查方案開發(fā)板和開發(fā)機互ping不通AP隔離開啟 / 不在同一網(wǎng)段檢查路由器設置、檢查WiFi連接ping通但NFS掛載卡住防火墻未放行 / rpcbind未啟動放行111和2049端口檢查rpcinfoNFS掛載報Permission deniedexports網(wǎng)段不對 / 缺少no_root_squash查看服務端syslog、檢查exportfsNFS掛載偶爾斷開無線省電模式 / 丟包率偏高關閉power_save、換5GHz頻段TFTP傳小文件成功大文件失敗WiFi丟包觸發(fā)頻繁重傳換有線驗證、換鏈路、減小文件uboot能tftp但內(nèi)核啟動后網(wǎng)絡不通uboot固定IP與內(nèi)核IP不一致路由器靜態(tài)綁定MAC、bootargs設靜態(tài)IPSELinux攔截導致掛載無反應Red Hat系默認SELinux強制setenforce 0驗證后配置布爾值6.1 掛載命令卡住不動怎么快速脫身NFS掛載命令一旦卡住最常見的錯誤操作是按CtrlC然后重試發(fā)現(xiàn)還是卡。原因是NFS cliente掛載進程已經(jīng)進入不可中斷的等待狀態(tài)D state普通信號殺不掉。我的處理方式# 先等軟掛載的timeo retrans周期走完 # 如果超過2分鐘還無響應強制卸載 umount -lf /mnt/nfs使用 umount -lf懶惰卸載可以強制解除掛載點然后檢查鏈路和服務端狀態(tài)確認沒問題再重新掛載。加了這個惰性卸載參數(shù)之后你就不用為了恢復環(huán)境而重啟整個開發(fā)板了。但注意省事不代表可以亂用頻繁強制卸載容易造成文件系統(tǒng)緩存未落盤。調(diào)試階段沒問題生產(chǎn)設備上不要這么干。6.2 服務端日志怎么高效利用NFS和TFTP的很多問題只在服務端日志里有線索客戶端界面只能給你一個籠統(tǒng)的錯誤碼。Debian系NFS在 /var/log/syslog 或 /var/log/messages 里Red Hat系在 /var/log/messages 里。每次出現(xiàn)問題時第一時間查這兩個日志比反復重啟客戶端高效太多。我之前遇到過一次開發(fā)板掛載NFS失敗排查了很久沒頭緒最后打開服務端日志看到一行 nfsd: request from unprivileged port才知道問題出在開發(fā)板把源端口映射到了高端口而服務端配置了安全端口限制。這個錯誤信息在客戶端完全不顯示不查日志根本無從入手。還有一點很多教程不會提TFTP上傳失敗時在/tftpboot目錄下查找同名零字節(jié)文件如果存在說明上次傳輸失敗了但殘留了空文件會影響下次傳輸或誤判文件完整性。我的習慣是每次做TFTP傳輸測試前先清空一下TFTP目錄里同名目標文件。6.3 TFTP傳輸大文件容易失敗的另類解法WiFi下TFTP傳大文件失敗已經(jīng)確認是丟包引發(fā)的重傳風暴后還有一個我親測有效的思路把要傳的大文件拆成若干小段用腳本循環(huán)傳。比如一個35MB的鏡像拆分成每段5MBTFTP逐段傳輸后重新拼接split -b 5M zImage zImage_part_ for part in zImage_part_*; do tftp -p 192.168.1.10 -l $part done在開發(fā)板上再把這幾個部分拼接回完整鏡像。這個辦法有點取巧對于“WiFi鏈路質(zhì)量不算太差但不穩(wěn)定”的環(huán)境很有效。如果鏈路質(zhì)量已經(jīng)很差拆成多段依然會失敗那就不如老老實實解決信號問題。這個方法不適合日常工作流只適合應急比如你人在現(xiàn)場手頭沒有網(wǎng)線但內(nèi)核編譯好了必須馬上傳到板子上驗證。絕大多數(shù)情況下我更建議Wireless環(huán)境里能用NFS就NFS能用串口傳小文件就串口傳。6.4 不同開發(fā)板的WiFi行為差異市面上的開發(fā)板WiFi模塊千差萬別同樣是WiFi有的板子連上什么都不干就很穩(wěn)定有的板子省電模式關不掉、驅(qū)動有bugNFS時不時掉線。遇到后者別死磕服務端配置先查無線驅(qū)動和固件版本。我遇到過的情況是某開發(fā)板的WiFi驅(qū)動在某種路由器上場掃描行為異常表現(xiàn)為每隔固定時間就掉線重連。最后通過升級內(nèi)核模塊才徹底解決。這個經(jīng)驗的意思是如果你的服務端配置、防火墻、信號質(zhì)量都排查完了仍然不穩(wěn)定去看無線網(wǎng)卡驅(qū)動是不是有已知bug。還有一個再小不過但是影響鏈路穩(wěn)定性的點無線電源管理。很多開發(fā)板默認啟用省電模式啟動調(diào)試時CPU是省不了多少電的但網(wǎng)卡會頻繁休眠。在代碼里加一條 iw dev wlan0 set power_save off 的成本低于后面排查隨機斷連的時間成本。最后分享一個我自己的習慣我會在開發(fā)機上留一個啟動腳本把NFS服務、TFTP服務、防火墻狀態(tài)一次檢查完輸出一份清晰的報告。在WiFi調(diào)試這種多環(huán)節(jié)的場景里腳本檢查比手工排查可靠得多每次改完環(huán)境配置跑一遍能節(jié)省大量時間。這套WiFi模式下的NFSTFTP環(huán)境本質(zhì)上就是處理好三件事服務端正確導出、客戶端選用適配無線鏈路的掛載參數(shù)、鏈路質(zhì)量足夠可靠。從有線轉(zhuǎn)到無線千萬不要以為只是換了傳輸介質(zhì)鏈路特征變了參數(shù)和排查思路都要跟著變。希望這些從現(xiàn)場踩坑里總結(jié)出來的經(jīng)驗能幫你少走一些彎路。