線網(wǎng)卡Linux驅(qū)動(dòng)編譯安裝與排錯(cuò)指南)
簡(jiǎn)介這是一份面向Linux/Android系統(tǒng)開(kāi)發(fā)者及嵌入式工程師的無(wú)線網(wǎng)卡驅(qū)動(dòng)資源包對(duì)應(yīng)EW-7822UMXRealtek RTL8832BU/RTL8852BU方案在Linux及Android 8.0~12.x平臺(tái)上的驅(qū)動(dòng)與配套組件解決該設(shè)備在開(kāi)源系統(tǒng)下無(wú)法識(shí)別、Wi-Fi連接不穩(wěn)定或功能受限等問(wèn)題。壓縮包為ZIP格式共51個(gè)文件總大小27.83MB以PDF技術(shù)文檔、GZ壓縮源碼包、conf配置模板為主體另含少量txt說(shuō)明、diff補(bǔ)丁、sh安裝腳本等覆蓋驅(qū)動(dòng)源碼、wpa_supplicant與hostapd配置、Android SDK參考代碼及并發(fā)模式、WPA3、TDLS、節(jié)能等專題文檔。包內(nèi)提供的多版本適配代碼、編譯安裝腳本和Quick Start指南可幫助用戶快速完成驅(qū)動(dòng)交叉編譯、系統(tǒng)移植與無(wú)線功能調(diào)試尤其適合定制固件或維護(hù)第三方ROM的開(kāi)發(fā)者參考。目前已有211人學(xué)習(xí)按版本號(hào)迭代規(guī)律推測(cè)該驅(qū)動(dòng)修復(fù)了已知兼容性問(wèn)題并新增部分功能值得相關(guān)項(xiàng)目按需選用。1. EW-7822UMX Linux 驅(qū)動(dòng)包它解決的痛點(diǎn)和需要你親手編譯的真相很多桌面 Linux 用戶第一次下載 EW-7822UMX_Linux_Driver_1.0.0.2.zip 時(shí)心里想的是“裝個(gè)驅(qū)動(dòng)解壓就能用”。等雙擊解壓后才發(fā)現(xiàn)里面根本沒(méi)有安裝腳本而是一堆 C 源碼、Makefile 和固件目錄。這不是打包人偷懶而是這類 USB 無(wú)線網(wǎng)卡在 Linux 下的宿命內(nèi)核自帶驅(qū)動(dòng)跟不上硬件廠商只能把帶源碼的驅(qū)動(dòng)包作為標(biāo)準(zhǔn)交付物。這個(gè)包解決的問(wèn)題很具體讓以 0bda:8822c 為 USB 廠商 ID 的 802.11ac 雙頻網(wǎng)卡在主流內(nèi)核上能用完整功能——包括 5GHz 頻段、80MHz 帶寬和 AP 模式。和它打交道的人主要是三類把無(wú)線網(wǎng)卡插在工控機(jī)上的嵌入式系統(tǒng)開(kāi)發(fā)者、剛把筆記本切成 Linux 的桌面用戶以及維護(hù)無(wú)線路由器開(kāi)源系統(tǒng)的玩家。如果你只是想知道“我這個(gè)網(wǎng)卡怎么聯(lián)網(wǎng)”最需要看的是第 4 章和第 5 章的加載與排查如果你要長(zhǎng)期維護(hù)多臺(tái)設(shè)備第 6 章的 DKMS 習(xí)慣能省掉大量重復(fù)勞動(dòng)。和 Windows 下的安裝包不同這個(gè) zip 文件從解壓那一刻起就考驗(yàn)?zāi)銓?duì)內(nèi)核模塊、Secure Boot、USB 電源管理這幾件事的理解。整個(gè)過(guò)程不復(fù)雜但每一步都有各自的坑而且這些坑相互獨(dú)立頭文件沒(méi)裝好會(huì)編譯失敗簽名沒(méi)處理會(huì)加載失敗電源管理沒(méi)關(guān)可能讓網(wǎng)卡隔幾分鐘就消失一次。所以這篇內(nèi)容的順序是按“識(shí)別芯片 → 準(zhǔn)備環(huán)境 → 編譯 → 加載 → 排錯(cuò) → 長(zhǎng)期維護(hù)”來(lái)組織的照著走基本不會(huì)翻車。2. 裝驅(qū)動(dòng)前先認(rèn)芯片lsusb 識(shí)別、壓縮包結(jié)構(gòu)與內(nèi)核依賴2.1 一條 lsusb 命令確認(rèn)芯片型號(hào)和驅(qū)動(dòng)歸屬在解壓驅(qū)動(dòng)包之前先花十秒鐘確認(rèn)網(wǎng)卡的 USB ID。USB 無(wú)線網(wǎng)卡和顯卡、聲卡不一樣同一個(gè)外觀型號(hào)在不同批次里裝不同芯片的情況并不罕見(jiàn)尤其是市面上大量公模產(chǎn)品。如果芯片方案和驅(qū)動(dòng)包不對(duì)應(yīng)后面所有 make 成功、modprobe 不報(bào)錯(cuò)也不會(huì)有 wlan 接口出現(xiàn)。lsusb # 輸出示例 # Bus 001 Device 004: ID 0bda:8822c 802.11ac Adapter # Bus 001 Device 005: ID 0bda:8152 2.5G Ethernet看到 0bda 開(kāi)頭的 ID基本可以斷定是常見(jiàn)的那套 USB 無(wú)線方案。先用lsusb -v -s 004查看更多端點(diǎn)描述確認(rèn)它是不是 802.11ac 雙頻。這個(gè)步驟的意義在于你要在后面知道加載模塊時(shí)該用哪個(gè)名字以及內(nèi)核自帶驅(qū)動(dòng)rtw88/rtw89 或 staging 下的 rtl8822cu是不是已經(jīng)搶先綁定了設(shè)備。如果lsusb顯示的是一個(gè)沒(méi)見(jiàn)過(guò)的廠商 ID那就得先查它的 Linux 驅(qū)動(dòng)支持現(xiàn)狀不要硬編譯這個(gè)包。另一個(gè)容易被忽略的問(wèn)題是 USB 模式轉(zhuǎn)換。部分 802.11ac 網(wǎng)卡出廠時(shí)固件里有其它用途的描述符在 Linux 下第一次插上會(huì)被識(shí)別成普通存儲(chǔ)設(shè)備或未知設(shè)備需要模式切換工具處理。這種時(shí)候 lsusb 看到的 ID 不是 0bda:8822c而是廠商對(duì)應(yīng)的引導(dǎo) ID。常見(jiàn)做法是使用 usb_modeswitch 配置一條 udev 規(guī)則在插入瞬間發(fā)送切換序列。# 查看內(nèi)核是否已經(jīng)識(shí)別成 802.11 設(shè)備 dmesg | grep -i -E usb|wlan|802.11 | tail -n 20如果 dmesg 里出現(xiàn) “cfg80211: Loaded X.509 cert” 或 “rtw_8822cu” 這類日志說(shuō)明內(nèi)核自帶驅(qū)動(dòng)已經(jīng)在工作。此時(shí)不要急著編譯新驅(qū)動(dòng)先確認(rèn)現(xiàn)有驅(qū)動(dòng)是不是夠用有些發(fā)行版自帶驅(qū)動(dòng)的固件文件缺失導(dǎo)致能識(shí)別設(shè)備但掃描不到網(wǎng)絡(luò)。這種“半驅(qū)動(dòng)”狀態(tài)正是很多人誤以為硬件壞了的原因。2.2 壓縮包里通常有什么以及為什么不能跨內(nèi)核直接 insmod把 EW-7822UMX_Linux_Driver_1.0.0.2.zip 解壓后一般會(huì)得到一個(gè)以芯片方案命名的目錄。里面除了 README還會(huì)出現(xiàn) core、hal、os_dep 這些源碼目錄以及一個(gè) Makefile。os_dep 是操作系統(tǒng)適配層負(fù)責(zé)對(duì)接 Linux 的網(wǎng)絡(luò)協(xié)議棧core 是 802.11 協(xié)議核心hal 是硬件抽象層不同頻段和信道的射頻參數(shù)都在這層。這種三層結(jié)構(gòu)是這類 USB 無(wú)線驅(qū)動(dòng)包的標(biāo)準(zhǔn)骨架。unzip EW-7822UMX_Linux_Driver_1.0.0.2.zip cd EW-7822UMX_Linux_Driver_1.0.0.2/ find . -maxdepth 2 -type d | sort # 常見(jiàn)輸出 # ./core # ./hal # ./os_dep # ./platform不要嘗試把編譯好的 .ko 文件復(fù)制到別的內(nèi)核上 insmod。Linux 內(nèi)核模塊對(duì)編譯它的內(nèi)核頭文件版本有強(qiáng)依賴vermagic 不一致時(shí)會(huì)直接報(bào) “module version magic mismatch”即使版本號(hào)一致struct 布局變化也可能造成內(nèi)存踩踏。這就是為什么這類驅(qū)動(dòng)包堅(jiān)持源碼分發(fā)你必須在目標(biāo)機(jī)器的當(dāng)前內(nèi)核上重新編譯一次。內(nèi)核依賴還不止版本匹配。編譯時(shí)要用到/lib/modules/$(uname -r)/build符號(hào)鏈接指向的內(nèi)核頭文件樹(shù)頭文件里的 Module.symvers 記錄了導(dǎo)出符號(hào)的 CRC。如果頭文件版本和運(yùn)行內(nèi)核不一致生成的模塊可能缺少部分符號(hào)引用加載時(shí)出現(xiàn) “Unknown symbol” 錯(cuò)誤。所以驅(qū)動(dòng)安裝第一步永遠(yuǎn)是確認(rèn)頭文件版本而不是急著去 make。到這里我建議你先把當(dāng)前系統(tǒng)的內(nèi)核版本、gcc 版本、Makefile 里的默認(rèn)平臺(tái)配置記下來(lái)。第 3 章講編譯環(huán)境準(zhǔn)備第 4 章講編譯加載這兩章是連在一起的環(huán)境不對(duì)編譯一定翻車。3. 編譯前準(zhǔn)備內(nèi)核頭文件、構(gòu)建工具和 Secure Boot 簽名3.1 安裝編譯依賴不同發(fā)行版三條命令對(duì)比多數(shù)發(fā)行版默認(rèn)不會(huì)裝內(nèi)核開(kāi)發(fā)包更不會(huì)把 gcc 完整工具鏈都帶上。對(duì)于這個(gè)驅(qū)動(dòng)包除了 gcc、make還需要內(nèi)核頭文件、libelf 和 openssl 開(kāi)發(fā)庫(kù)以及可選的 bc。我一般先確認(rèn)三件事內(nèi)核版本、頭文件是否可用、gcc 版本。uname -r gcc --version | head -n 1 ls -l /lib/modules/$(uname -r)/build如果第三個(gè)命令顯示的符號(hào)鏈接指向一個(gè)不存在的目錄說(shuō)明頭文件沒(méi)裝。Debian/Ubuntu 系執(zhí)行sudo apt update sudo apt install -y gcc make bc bison flex libelf-dev libssl-dev linux-headers-$(uname -r)Red Hat 系執(zhí)行sudo dnf install -y gcc make kernel-devel kernel-headers elfutils-libelf-devel openssl-devel裝完之后再次檢查/lib/modules/$(uname -r)/build確認(rèn)它真實(shí)存在。這里有個(gè)常見(jiàn)誤解很多人只裝了linux-headers-generic這種元包但運(yùn)行的是 HWE 內(nèi)核頭文件版本對(duì)不上。此刻不要怕麻煩直接按uname -r裝對(duì)應(yīng)的頭文件包例如linux-headers-6.8.0-45-generic。還需要注意 gcc 的版本。有些老驅(qū)動(dòng)包在編譯時(shí)用到了在新版本 gcc 里被移除的隱式函數(shù)聲明導(dǎo)致大量警告甚至錯(cuò)誤。如果編譯報(bào)錯(cuò)集中在 include/linux 下而與驅(qū)動(dòng)本身無(wú)關(guān)優(yōu)先檢查 gcc 是不是太新必要時(shí)降低 gcc 版本或使用make CCgcc-12這類方式指定編譯器這種編譯玄學(xué)在 2024 年之后的發(fā)行版上越來(lái)越常見(jiàn)。還有一個(gè)更穩(wěn)的選擇如果系統(tǒng)已經(jīng)裝了 DKMS可以讓 DKMS 幫你管理源碼和構(gòu)建過(guò)程但要用它必須有 dkms.conf這個(gè)在第 6.2 節(jié)展開(kāi)。對(duì)第一次接觸的人我的建議是先手工編譯一遍至少要明白驅(qū)動(dòng)源碼是怎么變成 .ko 文件的否則后續(xù)排錯(cuò)沒(méi)有方向感。3.2 Secure Boot 下的模塊簽名流程如果你不想在 UEFI 設(shè)置里關(guān)掉 Secure Boot就必須給編譯出來(lái)的模塊簽名。否則加載時(shí)會(huì)遇到 “Required key not available” 或 “Module signature verification failed”而 dmesg 里不會(huì)出現(xiàn)驅(qū)動(dòng)自己的報(bào)錯(cuò)排查起來(lái)特別繞。這里給出一個(gè)本地生成簽名密鑰并登記到 MOK 的流程。# 1) 生成自己的簽名密鑰證書 openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv \ -outform DER -out MOK.der -nodes -days 36500 \ -subj /CNUSB WiFi Module Key/ # 2) 導(dǎo)入 MOK重啟后按提示錄入密碼 sudo mokutil --import MOK.derMOK 導(dǎo)入后重啟會(huì)進(jìn)入藍(lán)色 MokManager 界面選擇 Enroll MOK from disk 并找到剛才的 der 文件然后錄入設(shè)置過(guò)的密碼完成登記。之后編譯出的模塊用 sign-file 簽名但前提是驅(qū)動(dòng)的 Makefile 里沒(méi)關(guān)掉簽名支持一般我們用一個(gè)腳本統(tǒng)一處理# 3) 簽名模塊文件 sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 \ MOK.priv MOK.der /path/to/8822cu.ko有些場(chǎng)景不適用這個(gè)方案比如內(nèi)核頭文件路徑里沒(méi)有 scripts/sign-file或目標(biāo)設(shè)備根本進(jìn)不了 MOK 流程。這種情況下短期開(kāi)發(fā)可以進(jìn) BIOS 把 Secure Boot 設(shè)為 Setup Mode 或直接關(guān)閉但長(zhǎng)期部署還是建議保留簽名。我認(rèn)識(shí)的一位朋友曾把設(shè)備放在生產(chǎn)環(huán)境每次內(nèi)核更新后模塊都因簽名失效而加載失敗最后排查到原因就是 UEFI 里 Secure Boot 被默認(rèn)打開(kāi)而簽名流程沒(méi)同步到部署文檔里。4. 最小安裝流程從 make 到 modprobe 的完整命令4.1 編譯安裝命令與三個(gè)常用 Makefile 參數(shù)確認(rèn)編譯環(huán)境沒(méi)問(wèn)題后正式編譯。絕大多數(shù)情況下進(jìn)入源碼根目錄直接 make 就能成功因?yàn)?Makefile 默認(rèn)會(huì)去讀/lib/modules/$(uname -r)/build這個(gè)鏈接。cd EW-7822UMX_Linux_Driver_1.0.0.2/ make clean # 如果之前失敗過(guò)先清掉 .o make -j$(nproc) sudo make installmake install 會(huì)把生成的 .ko 復(fù)制到/lib/modules/$(uname -r)/extra/或直接放到 kernel/drivers/net/wireless 下具體路徑由 Makefile 里的 MODDESTDIR 決定。參數(shù)說(shuō)明-j$(nproc)用所有 CPU 核心并行編譯但這個(gè)驅(qū)動(dòng)包的編譯過(guò)程比較脆弱部分源碼文件有隱式依賴并行度太高反而會(huì)出現(xiàn)隨機(jī)性編譯失敗。如果make -j翻車退回單線程的make再試一次往往就成了。如果目標(biāo)是 ARM 設(shè)備就不能直接 make。Makefile 里通常用 CONFIG_PLATFORM_XXX 區(qū)分不同平臺(tái)常見(jiàn)寫法如下參數(shù)示例作用CONFIG_PLATFORM_I386_PCy強(qiáng)制按 x86 平臺(tái)配置編譯桌面用默認(rèn)值即可KSRC/path/to/kernel/source指定自定義內(nèi)核源碼樹(shù)替代默認(rèn)的 build 鏈接CROSS_COMPILEaarch64-linux-gnu-交叉編譯工具鏈前綴給 ARM 設(shè)備編譯時(shí)必填CONFIG_PLATFORM_ARM_RPIy常見(jiàn)單板機(jī)平臺(tái)配置部分包用這個(gè)開(kāi)關(guān)切換設(shè)備樹(shù)相關(guān)代碼以交叉編譯為例常見(jiàn)做法是修改 Makefile 頂部的平臺(tái)開(kāi)關(guān)或直接在命令行傳入make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- \ KSRC/home/me/linux/ KDIR/home/me/linux/有人會(huì)問(wèn)為什么不直接用發(fā)行版?zhèn)}庫(kù)里的驅(qū)動(dòng)。答案很簡(jiǎn)單倉(cāng)庫(kù)驅(qū)動(dòng)往往滯后而且為了穩(wěn)定不會(huì)開(kāi)啟所有功能。這個(gè)包自帶 AP 模式、WDS 和 802.11d 等選項(xiàng)想開(kāi)這些功能只有編譯源碼。4.2 加載模塊和處理內(nèi)核自帶驅(qū)動(dòng)的搶先占用編譯安裝完成后不要馬上modprobe先檢查當(dāng)前是否有其它驅(qū)動(dòng)綁定。內(nèi)核自帶驅(qū)動(dòng)可能已經(jīng)綁定了設(shè)備如果不先卸載新模塊會(huì)因?yàn)?“Device or resource busy” 而加載失敗或者兩個(gè)模塊各自驅(qū)動(dòng)一半導(dǎo)致 wlan 反復(fù)消失。# 先看當(dāng)前占用 USB 無(wú)線設(shè)備的模塊 lsmod | grep -E 8822|rtw|cfg80211 # 卸載自帶驅(qū)動(dòng) sudo modprobe -r rtw_8822cu 2/dev/null || true # 加載新驅(qū)動(dòng) sudo modprobe 8822cu如果新驅(qū)動(dòng)模塊名和自帶驅(qū)動(dòng)名相同需要先把自帶驅(qū)動(dòng)列入黑名單。新建配置文件/etc/modprobe.d/blacklist-ew7822umx.conf寫入blacklist rtw_8822cu blacklist rtw88_8822cu install 8822cu /sbin/modprobe --ignore-install 8822cu倒數(shù)第二行的 install 語(yǔ)句是為了防止其它程序在加載 8822cu 時(shí)又把自帶驅(qū)動(dòng)拉起來(lái)。寫過(guò)之后執(zhí)行sudo update-initramfs -u更新 initramfs再重啟驗(yàn)證。這里注意一點(diǎn)如果編譯出來(lái)的模塊名就叫rtl8822cu或8822cu上面的文件名要跟著改確認(rèn)方式是在源碼目錄執(zhí)行l(wèi)s *.ko。模塊加載成功后ip link或iw dev應(yīng)該能看到類似wlx0011xxxx的接口名。沒(méi)有的話重新插拔一下 USB 設(shè)備并立刻看dmesg | tail -n 30。加載模塊的時(shí)序在 USB 設(shè)備探測(cè)之后而驅(qū)動(dòng)綁定是在模塊加載時(shí)觸發(fā)所以重新插拔是讓系統(tǒng)重新匹配設(shè)備的最簡(jiǎn)單辦法。5. 驅(qū)動(dòng)起不來(lái)的五個(gè)典型翻車現(xiàn)場(chǎng)與排查思路5.1 編譯直接報(bào) “No rule to make target ‘modules’”現(xiàn)象在源碼目錄執(zhí)行 make幾行輸出之后看到make[1]: *** No rule to make target modules. Stop.原因沒(méi)有找到內(nèi)核頭文件的構(gòu)建目錄。Makefile 依賴/lib/modules/$(uname -r)/build指向的路徑這個(gè)路徑不存在modules 目標(biāo)就找不到。解決不要在這時(shí)去改 Makefile先把頭文件安裝好。對(duì)多數(shù)發(fā)行版安裝linux-headers-$(uname -r)或者kernel-devel即可。安裝完檢查/lib/modules/$(uname -r)/build/Makefile是否存在再回到源碼目錄執(zhí)行make clean make。如果頭文件存在但編譯仍失敗確認(rèn)是不是自定義編譯內(nèi)核這時(shí)需要手動(dòng)指定KSRC/usr/src/linux-xxx。5.2 modprobe 報(bào) “Required key not available”現(xiàn)象模塊編譯成功但 modprobe 時(shí)返回錯(cuò)誤dmesg 最后幾行出現(xiàn)Required key not available或Module signature verification failed。原因Secure Boot 開(kāi)啟內(nèi)核只接受有有效簽名的模塊。自己編譯的模塊沒(méi)有經(jīng)過(guò)任何可信密鑰簽名。解決兩個(gè)方向。方向上策是生成 MOK 密鑰并導(dǎo)入給 .ko 簽名方向下策是進(jìn) BIOS 關(guān)閉 Secure Boot。上策的具體命令見(jiàn)第 3.2 節(jié)。這里補(bǔ)充一個(gè)細(xì)節(jié)簽名要用內(nèi)核源碼樹(shù)里的 sign-file不要用自己找的腳本否則證書格式不對(duì)依然會(huì)被拒絕。簽名后再modprobe -v 8822cu看到Using /lib/modules/.../extra/8822cu.ko這類輸出就說(shuō)明模塊已被接受。5.3 加載成功但 iw dev 看不到 wlan 接口現(xiàn)象lsmod | grep 8822有輸出dmesg也沒(méi)有錯(cuò)誤但iw dev里沒(méi)有任何無(wú)線設(shè)備。原因最常見(jiàn)的是兩個(gè)驅(qū)動(dòng)同時(shí)存在比如內(nèi)核自帶的rtw_8822cu已經(jīng)搶占了 device廠商模塊加載后沒(méi)有獲得 USB 接口或者是模塊加載時(shí) USB 設(shè)備還沒(méi)完成識(shí)別cfg80211 注冊(cè)的 wiphy 沒(méi)有對(duì)應(yīng)到 netdev。解決先把機(jī)器上所有自帶驅(qū)動(dòng)模塊全部卸載也可以使用第 4.2 節(jié)的黑名單。然后執(zhí)行sudo modprobe -r 8822cu重新插拔 USB 網(wǎng)卡等待 3-5 秒再加載模塊。如果仍沒(méi)接口用dmesg -w實(shí)時(shí)看內(nèi)核日志重新插拔時(shí)應(yīng)該能看到從usb 1-2: new high-speed USB device到cfg80211: Loading compiled-in X.509 certificates的過(guò)程。日志在rtw_8822cu附近中斷就說(shuō)明驅(qū)動(dòng)注冊(cè) netdev 的路徑?jīng)]走通重點(diǎn)檢查模塊參數(shù) ifname 和驅(qū)動(dòng)日志級(jí)別。5.4 連接后頻繁斷流或休眠喚醒后網(wǎng)卡消失現(xiàn)象連接 Wi-Fi 正常但過(guò)幾分鐘延遲飆升或筆記本合蓋休眠喚醒后網(wǎng)絡(luò)顯示已連接但無(wú)法訪問(wèn)ping 超時(shí)嚴(yán)重。原因USB 網(wǎng)卡的電源管理被默認(rèn)打開(kāi)。iwconfig 顯示 Power Management:on 時(shí)網(wǎng)卡會(huì)自動(dòng)進(jìn)入低功耗狀態(tài)USB 設(shè)備的檢測(cè)和喚醒又不太可靠就會(huì)出現(xiàn)斷流假象。這里的坑在于很多發(fā)行版的 NetworkManager 默認(rèn)給所有無(wú)線網(wǎng)卡開(kāi)省電。解決關(guān)閉電源管理執(zhí)行sudo iw dev wlan0 set power_save off如果要做成永久配置可以在 NetworkManager 的 wifi 連接配置里加入 powersave22 表示禁用或?qū)懸粭l udev 規(guī)則在設(shè)備出現(xiàn)時(shí)自動(dòng)關(guān)掉。下面是一個(gè)最小 udev 規(guī)則示例# /etc/udev/rules.d/90-ew7822umx-power.rules ACTIONadd, SUBSYSTEMnet, KERNELwlx*, RUN/sbin/iw dev %k set power_save off注意 %k 會(huì)替換成實(shí)際接口名所以規(guī)則里的 KERNEL 匹配模式要和網(wǎng)卡命名規(guī)則一致。如果你用的是 systemd 的 predictable naming接口名通常是 wlx 開(kāi)頭加 MAC上面這個(gè)規(guī)則就是為此設(shè)計(jì)的。5.5 內(nèi)核升級(jí)后驅(qū)動(dòng)直接罷工重編又報(bào) API 錯(cuò)誤現(xiàn)象升級(jí)內(nèi)核后原來(lái)能工作的模塊在重啟后無(wú)法加載重新 make 時(shí)出現(xiàn)implicit declaration of function或invalid type argument of -等錯(cuò)誤定位到的文件往往在 os_dep 目錄。原因內(nèi)核 API 變更。比如新內(nèi)核把struct net_device里的某些字段刪掉或改成了函數(shù)調(diào)用老驅(qū)動(dòng)源碼沒(méi)有適配這種變化。Linux 5.15 之后這類問(wèn)題很常見(jiàn)畢竟驅(qū)動(dòng)本身就是為某個(gè)內(nèi)核版本范圍寫的。解決先確認(rèn)錯(cuò)誤是不是和os_dep/linux/os_intfs.c相關(guān)如果是大版本 API 變化沒(méi)有什么優(yōu)雅的一行解決常見(jiàn)的幾條路是查看驅(qū)動(dòng)包是否有更新版本在源碼里按內(nèi)核版本增加條件編譯或者改用內(nèi)核自帶驅(qū)動(dòng)放棄廠商擴(kuò)展功能。走上策的話給 Makefile 增加一行 EXTRA_CFLAGS# 在 EXTRA_CFLAGS 里添加適配宏示例非通用 EXTRA_CFLAGS -DUSE_CFG80211_STA_EVENT但這個(gè)只能解決個(gè)別函數(shù)缺失問(wèn)題。更長(zhǎng)期的解法是放棄手工編譯把源碼交給 DKMS讓每次內(nèi)核更新時(shí)自動(dòng)重新編譯這個(gè)具體配置放在第 6.2 節(jié)。6. 裝完只是開(kāi)始驗(yàn)證性能并讓驅(qū)動(dòng)跟著內(nèi)核平滑升級(jí)6.1 用 iw 和 iperf3 驗(yàn)證驅(qū)動(dòng)真實(shí)狀態(tài)驅(qū)動(dòng)裝上不代表參數(shù)正確。我一般用三段命令確認(rèn)先看鏈路協(xié)商參數(shù)再看連接質(zhì)量最后用 iperf3 打流測(cè)實(shí)際吞吐。iw dev wlan0 info iw dev wlan0 link第一段輸出里要重點(diǎn)看 txpower 和 freq如果 5GHz 頻段的 txpower 顯示偏低且信道始終落在 36-48可能是國(guó)家碼沒(méi)設(shè)置正確??梢杂胕w reg get查看當(dāng)前區(qū)域并按當(dāng)?shù)乇O(jiān)管規(guī)定設(shè)置正確的國(guó)家碼錯(cuò)誤的區(qū)域設(shè)置不僅可能影響可用信道還會(huì)讓發(fā)射功率被限得偏低。iperf3 -c 192.168.1.10 -t 30 -i 5打流時(shí)留意 retrans 值和吞吐曲線。如果近距離 80MHz 帶寬下吞吐明顯低于協(xié)商速率的一半先換一個(gè)干擾較少的信道再把 power_save off 設(shè)好。吞吐異常時(shí)先不要甩鍋給驅(qū)動(dòng)優(yōu)先用iw dev wlan0 survey dump看信道利用率很多時(shí)候是周圍 Wi-Fi 干擾。6.2 長(zhǎng)期維護(hù)的三個(gè)習(xí)慣DKMS、保留編譯日志、檢查固件路徑手工編譯的驅(qū)動(dòng)在內(nèi)核更新后會(huì)失效沒(méi)有比這更影響心情的事了。把驅(qū)動(dòng)目錄交給 DKMS 可以免掉大部分痛苦。前提是驅(qū)動(dòng)包里能寫一個(gè)簡(jiǎn)單的 dkms.conf內(nèi)容大致如下# dkms.conf PACKAGE_NAMEew7822umx PACKAGE_VERSION1.0.0.2 BUILT_MODULE_NAME[0]8822cu DEST_MODULE_LOCATION[0]/kernel/drivers/net/wireless MAKE[0]make KSRC${kernel_source_dir} CLEANmake clean AUTOINSTALLyes保存到源碼目錄后執(zhí)行sudo dkms add . sudo dkms build -m ew7822umx -v 1.0.0.2 sudo dkms install -m ew7822umx -v 1.0.0.2dkms.conf 里的參數(shù)說(shuō)明BUILT_MODULE_NAME 要和 make 生成的 .ko 文件名一致DEST_MODULE_LOCATION 決定安裝路徑MAKE[0] 里的${kernel_source_dir}是 DKMS 自動(dòng)展開(kāi)的內(nèi)核源碼路徑變量。如果驅(qū)動(dòng) Makefile 對(duì)路徑的讀取方式比較特殊DEST_MODULE_LOCATION 可能并不生效這時(shí)可以直接在 MAKE 命令里指定模塊復(fù)制路徑。第二個(gè)習(xí)慣是保留一份編譯日志。當(dāng)遇到第 5.5 節(jié)的 API 錯(cuò)誤時(shí)舊日志能快速定位是哪個(gè)內(nèi)核版本開(kāi)始出問(wèn)題、錯(cuò)誤涉及哪些函數(shù)否則只能重新跑一次 make 浪費(fèi)時(shí)間。第三個(gè)習(xí)慣是每次更新內(nèi)核后檢查固件文件路徑。這類 USB 驅(qū)動(dòng)除了 .ko還需要 firmware 文件常見(jiàn)的取固件方式是驅(qū)動(dòng)在加載時(shí)請(qǐng)求固件數(shù)據(jù)。如果/lib/firmware/下固件缺失模塊加載不報(bào)錯(cuò)但設(shè)備無(wú)法掃描。建議更新系統(tǒng)前先確認(rèn)固件還在丟了的話從驅(qū)動(dòng)包的 firmware 目錄復(fù)制一份即可。我自己吃過(guò)不少虧最深刻的一次是批量升級(jí)內(nèi)核后一批設(shè)備全部掉線最后發(fā)現(xiàn)是 Secure Boot 策略和 DKMS 簽名流程沒(méi)同步光重編模塊沒(méi)用。從那以后任何 USB 無(wú)線網(wǎng)卡驅(qū)動(dòng)我都堅(jiān)持這套習(xí)慣先 lsusb 確認(rèn)芯片再用 DKMS 管版本最后把電源管理和簽名問(wèn)題寫進(jìn)部署文檔。希望這些經(jīng)驗(yàn)?zāi)軒湍惆堰@張網(wǎng)卡一次跑穩(wěn)少走彎路希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取