卡驅(qū)動實戰(zhàn):識別、編譯與排查全流程)
簡介瑞昱RTL8168B是常見的PCI-E接口以太網(wǎng)控制芯片多用于臺式機與服務(wù)器主板。在Linux發(fā)行版如Fedora 6中只有安裝對應(yīng)驅(qū)動后才能正常識別網(wǎng)卡并建立有線網(wǎng)絡(luò)連接。這份資源提供該網(wǎng)卡的官方驅(qū)動源碼包版本r8168-8.013.00壓縮包共11個文件包含C語言源碼、頭文件、makefile編譯腳本、htm格式安裝說明及readme文檔包體僅58KB適合需要手動編譯驅(qū)動的用戶快速獲取。通過編譯并加載該驅(qū)動模塊讀者可以熟悉Linux內(nèi)核模塊管理的基本操作了解configure、make、modprobe等命令的實際用法并學(xué)會使用ifconfig或ip addr驗證網(wǎng)卡狀態(tài)。由于Fedora 6是較老發(fā)行版編譯過程中容易遇到內(nèi)核頭文件不匹配、依賴缺失等問題資源附帶的說明文檔提供了針對性的排錯指引。目前該資源已有2869人學(xué)習(xí)下載適合Linux運維人員、系統(tǒng)管理員以及需要為舊版本系統(tǒng)配置硬件驅(qū)動的用戶參考。 裝了這么多年Linux十個里面有八個會把時間花在網(wǎng)卡驅(qū)動上尤其是碰上Realtek的網(wǎng)卡。Realtek的芯片出貨量大、覆蓋廣從百兆老網(wǎng)卡到2.5G/5G有線網(wǎng)卡再到各種USB無線網(wǎng)卡幾乎每個裝機佬的抽屜里都能翻出兩三塊。但Realtek官方對Linux的支持一直談不上積極官網(wǎng)掛出來的Linux驅(qū)動源碼很多年都不更新遇到新版內(nèi)核直接編譯不過而Linux內(nèi)核自帶的開源驅(qū)動雖然能用可碰上一些特殊型號要么識別不了要么速度跑不滿。這篇文章就從我實際裝機的經(jīng)歷出發(fā)把Linux系統(tǒng)下Realtek網(wǎng)卡驅(qū)動的型號識別、驅(qū)動選擇、源碼編譯、問題排查整套流程捋一遍希望對準(zhǔn)備在Linux下折騰網(wǎng)卡的朋友有點幫助。1. 先做身份確認你的網(wǎng)卡到底是什么型號驅(qū)動裝不上、裝完沒效果90%的情況不是驅(qū)動有問題而是壓根沒搞清楚自己手上是什么芯片。Realtek的網(wǎng)卡型號命名看著簡單但“RTL8111”“RTL8168”“RTL8125”這些編號在市面上經(jīng)?;熘猛粋€型號還可能有好幾個硬件版本驅(qū)動方案完全不同。所以第一步不是下載驅(qū)動而是先把網(wǎng)卡的準(zhǔn)確型號和接口類型摸清楚。1.1 有線網(wǎng)卡lspci一次定位有線網(wǎng)卡的識別最簡單直接執(zhí)行l(wèi)spci | grep -i ethernet輸出大概是這個樣子02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 15)看到這個輸出基本可以確定是RTL8111或RTL8168系列的千兆網(wǎng)卡。內(nèi)核自帶的r8169驅(qū)動一般可以直接驅(qū)動它但這只是“能用”后面再細說。如果是2.5G或5G的新卡輸出會是RTL8125或RTL8126之類的字樣需要重點確認內(nèi)核版本和驅(qū)動方案。如果lspci看不到任何Realtek有線網(wǎng)卡別急著下結(jié)論。有些主板把網(wǎng)卡走的是USB通道或者網(wǎng)卡在BIOS里被禁用了。先查BIOS設(shè)置確保板載網(wǎng)卡處于開啟狀態(tài)再說。還有一種情況是網(wǎng)卡沒有物理連接lspci也會顯示但用起來沒有任何反應(yīng)這時候優(yōu)先檢查網(wǎng)線和交換機端口。1.2 無線網(wǎng)卡不像你想的那么好認無線網(wǎng)卡的識別有兩種方式。如果網(wǎng)卡是PCIe接口板載或獨立插槽用上面的lspci命令就能看到比如“RTL8822BE”“RTL8852BE”等。但USB接口的無線網(wǎng)卡要換命令lsusb輸出類似Bus 002 Device 003: ID 0bda:b812 Realtek Semiconductor Corp. 802.11ac NIC注意看ID后面的數(shù)字0bda是Realtek的USB廠商ID后面那個b812才是具體芯片型號的線索。不過USB無線網(wǎng)卡經(jīng)常出現(xiàn)“套殼”問題比如芯片明明是RTL8192EU但設(shè)備ID被廠商改寫了lsusb只能看到廠商自定義的ID。這時候建議配合dmesg | grep -i realtek查看內(nèi)核識別信息或者直接拆開網(wǎng)卡看芯片絲印。踩過太多次坑了買USB網(wǎng)卡不拆殼看清楚芯片后續(xù)裝驅(qū)動基本靠猜。1.3 系統(tǒng)默認驅(qū)動能不能先頂上在動手編譯官方驅(qū)動之前先看看系統(tǒng)能不能用自帶驅(qū)動把網(wǎng)卡跑起來。插上網(wǎng)線或者USB網(wǎng)卡后執(zhí)行dmesg | grep -i r8169 dmesg | grep -i rtl如果有驅(qū)動加載成功的日志而且ip addr里已經(jīng)能看到網(wǎng)卡的IP地址那恭喜你最少基礎(chǔ)聯(lián)網(wǎng)沒問題。這時候就能先用系統(tǒng)自帶的源把編譯工具鏈裝好后面做任何操作都有退路。我個人的習(xí)慣是任何時候動網(wǎng)卡驅(qū)動之前先確保手上有一個可以用的聯(lián)網(wǎng)通道哪怕是手機USB共享網(wǎng)絡(luò)也行。反正在線裝依賴、下載源碼、查錯誤日志沒網(wǎng)絡(luò)寸步難行。2. 有線網(wǎng)卡驅(qū)動內(nèi)核自帶與官方源碼怎么取舍2.1 r8169能用但有時候只是“能用”Realtek的千兆有線網(wǎng)卡在內(nèi)核里對應(yīng)的是r8169驅(qū)動RTL8111、RTL8168、RTL8169這些經(jīng)典型號都被它接管。很多發(fā)行版默認就加載它系統(tǒng)裝完插上網(wǎng)線就能上網(wǎng)這也是大多數(shù)用戶覺得“Realtek沒坑”的原因。但“能上網(wǎng)”和“工作正?!笔莾纱a事。r8169在部分平臺上會出現(xiàn)兩個典型問題一是連接速率降級千兆寬帶只能跑出百兆速度執(zhí)行ethtool eth0看到的是Speed: 100Mb/s而不是1000Mb/s二是高負載下斷流尤其是跑大流量傳輸或者連續(xù)壓測時網(wǎng)卡突然無響應(yīng)dmesg里刷出大量超時日志。出現(xiàn)這些情況先別急著罵r8169排除一下網(wǎng)線、交換機和BIOS省電設(shè)置。確認硬件沒問題之后再考慮換官方驅(qū)動。而且有一個點容易被忽略r8169其實是個通用驅(qū)動它同時覆蓋了多個型號某些新內(nèi)核里對老型號的初始化邏輯做了改動反而會讓老網(wǎng)卡出現(xiàn)兼容性問題。這時候換回廠商驅(qū)動反而更穩(wěn)。2.2 什么時候必須換r8168/r8125啟動后懷疑驅(qū)動不對可以執(zhí)行l(wèi)smod | grep r8169如果加載的是r8169但你的網(wǎng)卡是RTL8111/8168并且頻繁掉線或速率不達標(biāo)那就該考慮用Realtek官方的r8168驅(qū)動替換掉內(nèi)核的r8169了。RTL8125、RTL8126這類2.5G/5G網(wǎng)卡則對應(yīng)官方驅(qū)動r8125如果你用的內(nèi)核版本比較舊內(nèi)置驅(qū)動很可能是當(dāng)成千兆網(wǎng)卡在跑這也要靠官方驅(qū)動才能發(fā)揮全部速率。這里必須說清楚一個概念內(nèi)核自帶的驅(qū)動和Realtek官網(wǎng)提供的驅(qū)動源碼是兩套獨立實現(xiàn)功能范圍不一樣。r8169是內(nèi)核社區(qū)維護的開源驅(qū)動優(yōu)點是跟內(nèi)核兼容性好升級內(nèi)核不用重新編譯缺點是遇到新硬件或某些特殊功能比如部分網(wǎng)卡支持的WOL、巨型幀、硬件時間戳支持不完整。r8168/r8125是Realtek官方發(fā)布的閉源驅(qū)動源碼優(yōu)點是對自家芯片的寄存器配置最準(zhǔn)確速率、功耗、溫度表現(xiàn)更符合“出廠參數(shù)”缺點是需要自己編譯而且內(nèi)核一升級就得重新來一遍除非你用DKMS機制把它自動化。2.3 官方驅(qū)動源碼編譯的完整流程以RTL8125為例到Realtek官網(wǎng)找到對應(yīng)型號的Linux驅(qū)動下載鏈接通常是一個tar.gz壓縮包。編譯安裝的完整流程如下# 先裝編譯工具鏈 sudo apt update sudo apt install -y build-essential dkms linux-headers-$(uname -r) # 解壓源碼 tar -xvf r8125-9.011.01.tar.bz2 cd r8125-9.011.01 # 編譯并安裝 sudo make -j$(nproc) sudo make install # 刷新模塊依賴 sudo depmod -a # 暫時手動加載測試 sudo modprobe r8125編譯過程如果沒有任何報錯執(zhí)行l(wèi)smod | grep r8125能看到模塊已加載再執(zhí)行ethtool eth0查看速度。很多年前我第一次編譯時直接卡在make找不到頭文件這一步其實原因就是忘了裝linux-headers-$(uname -r)。記住這個包名前面要帶一個內(nèi)核版本號也就是說如果你用的發(fā)行版是Ubuntu、Debian系上面的apt install只會裝最新版本的headers如果跟當(dāng)前運行內(nèi)核版本不匹配照樣報錯。可以先執(zhí)行uname -r確認版本號再手動指定sudo apt install linux-headers-$(uname -r)利用命令替換能保證安裝的就是當(dāng)前內(nèi)核對應(yīng)的頭文件。2.4 用DKMS把驅(qū)動固化成系統(tǒng)模塊直接make install的問題在于內(nèi)核一旦升級新內(nèi)核啟動后驅(qū)動就失效了因為編譯出來的.ko模塊只對當(dāng)時的編譯環(huán)境有效。所以強烈建議用DKMS來管理驅(qū)動一條命令把驅(qū)動注冊進系統(tǒng)以后每次內(nèi)核升級DKMS會自動重新編譯模塊# 在源碼目錄下 sudo make clean sudo dkms add . sudo dkms build -m r8125 -v 9.011.01 sudo dkms install -m r8125 -v 9.011.01版本號以你下載的源碼包為準(zhǔn)不同版本不同。執(zhí)行dkms status可以查看到當(dāng)前注冊的驅(qū)動狀態(tài)。這里有個細節(jié)dkms add .是讀取當(dāng)前目錄下的dkms.conf配置文件如果源碼包沒帶這個文件需要自己寫一份。好在官方驅(qū)動一般都會提供別亂改里面的參數(shù)。加載新驅(qū)動前建議先看下當(dāng)前是否有r8169在占用網(wǎng)卡。如果存在需要把新驅(qū)動名寫進/etc/modules同時把r8169加入黑名單比如創(chuàng)建/etc/modprobe.d/blacklist-r8169.conf寫入blacklist r8169然后把r8125加入自動加載echo r8125 | sudo tee -a /etc/modules重啟后執(zhí)行l(wèi)smod | grep r8125確認同時ethtool eth0確認速率。3. USB無線網(wǎng)卡驅(qū)動從源碼編譯到固件加載3.1 先看芯片再找驅(qū)動順序不能反USB無線網(wǎng)卡的水比有線深得多。同一個型號的網(wǎng)卡不同批次可能用了不同芯片同一個芯片不同廠商的驅(qū)動方案也可能不一樣。比如市面上常見的RTL8188EU、RTL8188GU、RTL8192EU、RTL8821CU、RTL8822BU驅(qū)動源碼完全不是一套用錯驅(qū)動不但編譯不過就算勉強編譯出來也加載不了。識別芯片的準(zhǔn)確方法還是lsusb加dmesg把設(shè)備ID記下來然后去搜索引擎查“芯片型號 linux driver”基本都能找到Linux社區(qū)維護的開源驅(qū)動倉庫。這個搜索動作千萬不能省因為Realtek官方很多USB無線網(wǎng)卡的Linux驅(qū)動更新極慢甚至連新內(nèi)核的適配都沒有直接下官網(wǎng)源碼編譯大概率報錯。第三方倉庫反而維護積極適配了新內(nèi)核的API比如aircrack-ng/rtl8188eus、morrownr/rtl88x2bu這些開源項目比官方代碼靠譜得多。3.2 第三方開源驅(qū)動與官方代碼怎么選選第三方開源驅(qū)動不是因為它免費而是因為它解決了“能在新內(nèi)核上編譯通過”這個最基本的問題。以RTL8188EU為例內(nèi)核從5.15開始把內(nèi)部API改了不少官方2012年左右的老代碼在6.x內(nèi)核上根本編譯不過但社區(qū)維護的rtl8188eus項目持續(xù)跟進make一次就能過。第三方驅(qū)動倉庫的編譯流程和官方差別不大以rtl88x2bu為例git clone https://github.com/morrownr/rtl88x2bu.git cd rtl88x2bu sudo make -j$(nproc) sudo make install sudo modprobe 88x2bu注意驅(qū)動模塊名可能是88x2bu而不是rtl88x2bu加載前先用lsmod看看有沒有舊的同功能模塊有的話先modprobe -r卸載掉避免兩個驅(qū)動搶同一個USB設(shè)備。如果你只是在桌面環(huán)境用個無線網(wǎng)卡上網(wǎng)優(yōu)先選DKMS模式安裝。第三方倉庫很多都在README里給了DKMS安裝說明千萬別嫌麻煩跳過不然每次內(nèi)核升級之后無線網(wǎng)卡就“消失”那感覺真的很難受。3.3 固件缺失最容易忽略的一環(huán)源碼編譯成功、模塊加載正常但網(wǎng)卡就是掃描不到WiFi這時候大概率是固件文件缺失。Realtek網(wǎng)卡的無線部分除了驅(qū)動模塊外還需要把芯片運行時的固件載入硬件。固件文件一般放在/lib/firmware/rtlwifi/目錄下如果缺少對應(yīng)文件dmesg日志里會出現(xiàn)類似“rtl8188eu: firmware rtle.fw not found”的報錯。遇到這種情況安裝發(fā)行版的固件包即可Debian/Ubuntu系可以執(zhí)行sudo apt install firmware-realtek裝完重啟或者重新插拔網(wǎng)卡再看dmesg日志。這里要提醒一句有些第三方驅(qū)動倉庫會把固件文件一起打包進安裝腳本有些不會。如果按README裝完還是掃不到WiFi第一反應(yīng)就去看dmesg別反復(fù)重編譯。4. 問題排查實錄編譯報錯、加載失敗、跑不滿速4.1 編譯階段最常見的報錯速查源碼編譯是踩坑重災(zāi)區(qū)。我整理了一張速查表基本能覆蓋八成常見問題。現(xiàn)象原因處理方法make: *** No rule to make target modules內(nèi)核頭文件沒有安裝或不匹配安裝linux-headers-$(uname -r)fatal error: linux/compiler.h: No such file or directory內(nèi)核頭文件版本不對確認/usr/src下頭文件目錄與uname -r對應(yīng)error: implicit declaration of function ...內(nèi)核API版本太新老驅(qū)動不兼容換用社區(qū)維護的新驅(qū)動源碼selinux is enabled安裝模塊被拒SELinux攔截內(nèi)核模塊加載改用官方簽名模塊或臨時setenforce 0測試insmod: ERROR: could not insert module: Unknown symbol驅(qū)動與當(dāng)前內(nèi)核版本不匹配全部重編確保使用當(dāng)前內(nèi)核的headers編譯編譯報錯還有個通用排查思路打開源碼里的Makefile看開頭的內(nèi)核路徑KDIR是否指向了正確的頭文件目錄。大部分情況是指向/lib/modules/$(shell uname -r)/build但如果你用的是云服務(wù)器或定制內(nèi)核這個路徑可能是空的所以編譯前先檢查一下這個build目錄是否存在。4.2 模塊加載失敗與安全啟動模塊編譯好了modprobe加載卻報錯“Required key not available”或者“Module has invalid signature”這是安全啟動Secure Boot在攔路?,F(xiàn)在很多預(yù)裝Win11的筆記本默認開啟Secure BootLinux內(nèi)核在啟動時會校驗內(nèi)核模塊的簽名未簽名的第三方驅(qū)動會被拒絕加載。解決方式有兩種。第一種是臨時關(guān)閉Secure Boot進BIOS里找到Secure Boot選項并禁用簡單粗暴但對安全敏感的場景不太友好。第二種是使用mokutil工具給模塊簽名在Ubuntu系下可以這樣操作sudo mokutil --disable-validation設(shè)置一個密碼并重啟在藍色MOK管理界面里確認操作。這里有個細節(jié)MOK管理只有重啟后進入藍色界面才能確認密碼要記住不然重啟后會卡在驗證環(huán)節(jié)。4.3 網(wǎng)卡起來了速度不對優(yōu)先查這幾處驅(qū)動加載成功不代表速度正常。如果我碰到速率不達標(biāo)的情況按下面的順序排查先用ethtool eth0看當(dāng)前協(xié)商速率如果顯示100Mb/s拔插網(wǎng)線、更換網(wǎng)線再看貓和交換機端口是否支持千兆。很多時候問題根本不在驅(qū)動。查看dmesg | grep -i r8169/rtl是否有“l(fā)ink down”“carrier lost”之類日志有的話重點檢查網(wǎng)口的省電模式BIOS里把綠色以太網(wǎng)、節(jié)能以太網(wǎng)這類選項關(guān)掉。測試大文件傳輸用iperf3打流。如果單線程跑不滿試試多線程無線網(wǎng)卡跑不滿屬于正常有線網(wǎng)卡要是單線程跑不滿基本可以認定驅(qū)動或網(wǎng)線有問題。最終手段是換回內(nèi)核自帶驅(qū)動或換驅(qū)動版本交叉對比。Realtek的驅(qū)動版本跨度大有時舊驅(qū)動在某個內(nèi)核上表現(xiàn)反而更穩(wěn)定別死磕最新版。5. 特殊環(huán)境下的驅(qū)動方案5.1 服務(wù)器平臺與整機定制驅(qū)動服務(wù)器采購回來后自己裝Linux系統(tǒng)網(wǎng)卡識別不出來這種情況在Realtek芯片上不算罕見。服務(wù)器主板上的網(wǎng)卡大多是板載多口千兆或萬兆但部分型號的網(wǎng)卡是“Realtek芯片 廠商自定義固件”標(biāo)準(zhǔn)的r8169驅(qū)動能識別出硬件卻拿不到完整的MAC地址或者PHY初始化順序不對。碰到這種問題優(yōu)先去整機廠商的官網(wǎng)找“Linux驅(qū)動”或“網(wǎng)卡固件更新”頁面下載驅(qū)動包時注意選擇內(nèi)核版本對應(yīng)的版本。廠商定制驅(qū)動和Realtek官方源碼的區(qū)別在于它會額外帶上PHY初始化腳本和自定義的device ID映射編譯方式大多類似但可能在Makefile里預(yù)置了額外的宏定義所以盡量別拿官方通用版去替代。如果實在找不到定制版也可以先用臨時無線網(wǎng)卡聯(lián)網(wǎng)把dmidecode的信息和網(wǎng)卡ID記錄好再去社區(qū)里搜關(guān)鍵詞往往能找到別人的解決方案。5.2 國產(chǎn)Linux發(fā)行版下的兼容性國產(chǎn)主流Linux發(fā)行版比如Deepin、UOS、麒麟系列底層還是Debian或Fedora的體系所以驅(qū)動安裝方式和Ubuntu差別不太大。要注意的區(qū)別在于這些發(fā)行版默認內(nèi)核版本往往比較保守官方軟件源里不一定有build-essential和dkms需要手動開啟“開發(fā)者模式”或“源碼倉庫”后安裝。另外這些系統(tǒng)預(yù)裝的網(wǎng)卡驅(qū)動白名單可能和Debian官方不太一樣某些內(nèi)核模塊默認就被安全策略攔截了。比如我遇到過在UOS上編譯好的rtl8821cu模塊modprobe提示“Operation not permitted”查了半天才發(fā)現(xiàn)是系統(tǒng)的模塊加載策略沒放行需要在/etc/modprobe.d/下加一個allowlist文件把驅(qū)動名寫進去。這類問題不在Realtek官方文檔里只能靠多翻發(fā)行版社區(qū)帖子。6. 最后分享一個小習(xí)慣Realtek網(wǎng)卡驅(qū)動折騰得多了我養(yǎng)成一個習(xí)慣每次裝完驅(qū)動先把當(dāng)前生效的模塊名字、版本號、相關(guān)配置文件路徑記到文檔里同時執(zhí)行dkms status和modprobe -l把狀態(tài)快照下來。這個習(xí)慣幫我省了大量重復(fù)排查時間。畢竟Realtek的驅(qū)動體系相對分散有線和無線是兩套完全獨立的代碼USB和PCIe的芯片方案也不一樣指望一個通用方法解決所有型號不現(xiàn)實但有記錄、有日志、有對照表總能把問題一步步縮小到具體環(huán)節(jié)。希望這篇文章能幫你少走點彎路。本文還有配套的精品資源點擊獲取