在新買的聯想ideapad-330C筆記本上,安裝Ubuntu 18.04後,悲催的發現,沒有無線網路,幸好有線還能用,然後網上搜一波,發現不少人遇到這種問題,也有人給出解決方案 參考的鏈接: Thinkpad E470C(集成網卡rlt8111/8618/8411系列) 無線網卡rtl8821CE ...
在新買的聯想ideapad-330C筆記本上,安裝Ubuntu 18.04後,悲催的發現,沒有無線網路,幸好有線還能用,然後網上搜一波,發現不少人遇到這種問題,也有人給出解決方案
參考的鏈接: Thinkpad E470C(集成網卡rlt8111/8618/8411系列) 無線網卡rtl8821CE系列 安裝ubuntu 和win10雙系統沒有無線網問題 (侵刪)
在以上鏈接中給出瞭解決方案及無線網卡rtl8821ce源碼壓縮包的下載地址,有需要的自行去下載
系統:Ubuntu 18.04.2
內核: linux4.18
網卡:Realtek 8821CE Wireless LAN 802.11ac PCI-E NIC
按照參考鏈接的方法,成功安裝網卡驅動,在此電腦中也不用重啟就能連接wifi,但後來系統更新……到Ubuntu18.04.3,內核更新到linux5.0.0.31時,重啟後發現又沒有無線網卡的驅動
此時系統:Ubuntu 18.04.3
內核: linux5.0.0.31
只好按照原來的方法重新做一次,發現編譯就出錯了,配置沒有更改,make出現以下錯誤
rtl8821ce/os_dep/linux/os_intfs.c:1325:22: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] .ndo_select_queue = rtw_select_queue,
看這錯誤,也不知道發生什麼事啊,只好網上在找一下,找到了有人說是類型不匹配,然後在內核源碼中查找ndo_select_queue的聲明,找到了是這樣的
u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev, select_queue_fallback_t fallback);
而網卡裡的代碼 rtl8821ce/os_dep/linux/os_intfs.c:1192 是這樣的
static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) , void *accel_priv #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) , select_queue_fallback_t fallback #endif #endif
這樣只能修改網卡驅動的源碼了,改成適配linux5.0以上內核的,改為後代碼如下,添加了對內核linux5.0.0以上的判斷
static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) , struct net_device *sb_dev , select_queue_fallback_t fallback #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) , void *accel_priv #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) , select_queue_fallback_t fallback #endif #endif
改為保存,繼續make,又報錯
rtl8821ce/os_dep/linux/rtw_android.c:629:62: error: macro "access_ok" passed 3 arguments, but takes just 2 if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)) { ^ rtl8821ce/os_dep/linux/rtw_android.c:629:7: error: ‘access_ok’ undeclared (first use in this function) if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)) {
方法同上,繼續找access_ok在內核頭文件的聲明發現在linux5.0以上的 access_ok的參數只有2個,而網卡驅動上使用時有3個參數
手動修改網卡驅動源碼,文件: rtl8821ce/os_dep/linux/rtw_android.c :629,修改後如下:(刪除原來 if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)) { 這行代碼,添加以下代碼)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) if (!access_ok(priv_cmd.buf, priv_cmd.total_len)) { #else if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)) { #endif
保存,繼續make,又報錯,如下:
rtl8821ce/os_dep/linux/ioctl_cfg80211.c: In function ‘rtw_get_systime_us’: rtl8821ce/os_dep/linux/ioctl_cfg80211.c:339:2: error: implicit declaration of function ‘get_monotonic_boottime’; did you mean ‘getboottime’? [-Werror=implicit-function-declaration] get_monotonic_boottime(&ts); ^~~~~~~~~~~~~~~~~~~~~~ getboottime
這裡已經給了修改的提示了,不過同樣方法發現找不到 get_monotonic_boottime 這個函數,不過能找到提示的 getboottime函數,那就替換以下了,不過考慮到內核低於5.0的版本,那就加一個判斷了
同上刪除 rtl8821ce/os_dep/linux/ioctl_cfg80211.c:339 這行代碼,添加以下代碼
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) getboottime(&ts); #else get_monotonic_boottime(&ts); #endif
這次make終於成功了!
make sudo make install sudo modprobe -a 8821ce
這臺電腦不用重啟就直接連上原來的wifi了
沒幾天,電腦又更新了,重啟後發現又沒有了無線網卡驅動,看了一下,原來內核又升級了,這次是:
系統:Ubuntu 18.04.3
內核:Linux 5.0.0.32
內核一個小小改動,都讓原來的網卡驅動沒了,幸好上次的網卡驅動源碼的改動還在,重覆以下操作
make sudo make install sudo modprobe -a 8821ce
哈哈,又可以了