2021-06-25

linux驅動管理利器,詳解dkms工作原理 原文網址:https://kknews.cc/code/x6ay3yo.html

 

背景

最近遇到一個麻煩的問題,幾台伺服器在升級內核之後,新的內核啟動直接panic,無法正常驅動raid卡. 通過進入ramos,發現新的內核裡面沒有對應的raid卡驅動ko文件. 後面才發現老的內核中rraid卡驅動是從原始碼單獨編譯出來的. 換了新的kernel之後,忘了給新的內核重新編譯這個驅動就重啟了,導致kernel panic.

在linux中,每個驅動ko文件是與一個特定內核綁定的,也就是在老內核下面編譯的驅動在新內核下面無法使用,同樣的,在新內核下面編譯的驅動在老內核也無法使用.

在linux kernel原始碼樹中,已經包含了我們常見的很多驅動,那麼在安裝一個新的內核rpm包的時候,這些驅動也就被一起安裝了. 但是有些驅動不在原始碼樹裡面,這些驅動需要手動編譯安裝;還有一些驅動雖然在原始碼樹中,但是原始碼樹中的可能太老了,新的驅動也需要單獨編譯安裝.

使用dkms來管理原始碼樹外的驅動

dkms就是用來處理在kernel原始碼樹中不存在的驅動,或者我們自己維護的驅動的. 它可以保證新的kernel安裝之後,這些驅動被自動重新編譯,自動運行depmod命令,自動生成新的initram文件.

dkms這個工具存在於epel源中,需要先保證epel打開,然後yum -y install dkms就可以安裝這個工具了.使用rpm -ql dkms看下這個包安裝了什麼東西.

/usr/sbin/dkms是dkms命令行本身,是一個bash腳本.我們用的最多的是dkms status,用來查看當前dkms管理的驅動的狀態

/var/lib/dkms是dkms工作目錄.

/etc/kernel/目錄下面的兩個文件,分別是postinst和prerm的kernel hook,dkms自動管理驅動核心就是這兩個文件.

現在大部分驅動rpm包都有兩種形式的,一種是直接針對rhel特定版本(也就是特定內核)編譯好的. 還有就是一個dkms enabled的rpm包.

下面以megaraid_sas-07.710.06.00-1dkms.noarch.rpm這個dkms enabled包為例來操作.什麼是dkms enabled的rpm包呢

首先,這個rpm安裝文件的路徑一定是/usr/src/module-version目錄,比如這兒的/usr/src/megaraid_sas-07.710.06.00,然後這個包裡面一定有一個dkms.conf文件.

因為dkms工作的時候需要讀取這個dkms.conf文件,這個文件實際是一個shell腳本,dkms工作的時候會source進去.

我們看下安裝這個包的時候具體會做的事情

安裝之前,dkms status輸出為空,表示沒有管理任何驅動

這個包安裝的時候,會看到dkms add,dkms build(編譯驅動),dkms install(把編譯好的驅動安裝到/lib/modules/`uname -r`目錄下),跑depmod,跑dracut重新生成initramfs的過程(如果手動裝驅動,就是這些過程)

dkms enabled包的scripts,裡面是核心的dkms命令
dkms enabled包的安裝過程,能看到關鍵的步驟被執行

如果dkms只是能幫我們執行這些命令,那麼其實用處也不大. dkms最主要的用處是當我們安裝了一個新的kernel包之後,其會用到kernel hook給我們自動重新給新內核完成上面的事情.

dkms使用kernel hook自動管理驅動

在我們安裝了這個dkms enabled的驅動包之後,我們安裝一個新的內核

能看到這個新的kernel包安裝的過程中跑了一些腳本.

完成之後,dkms status直接顯示新的內核直接把這個驅動包安裝上了.

dkms的工作目錄/var/lib/dkms也顯示這個驅動包安裝到了新的內核.

那麼dkms在安裝新的內核包的時候,怎麼觸發給新的內核包重新編譯驅動的呢?

我們看下內核包的scripts,發現裡面有對/usr/sbin/new-kernel-pkg腳本的調用

而/usr/sbin/new-kernel-pkg裡面有對/etc/kernel/postinst.d/目錄下的腳本進行調用的邏輯.

dkms給/etc/kernel/postinst.d下面安裝了腳本

這個腳本裡面調用/usr/lib/dkms/dkms_autoinstaller進行自動安裝

dkms_autoinstaller調用dkms autoinstall,在autoinstall中,會對當前所有狀態為installed,並且dkms.conf配置匯總AUTOINSTALL=yes的模塊對安裝的內核進行編譯安裝.

總結

dkms是dell做的一個自動管理kernel原始碼樹外的驅動框架,現在大量用於各種硬體,特別是存儲硬體的驅動管理中. 其使用方法特別簡單,只需要將一個dkms enabled的原始碼包安裝即可. 後面的事情就是dkms自己處理了. 大家找硬體驅動包的時候可以找dkms enabled的,如果沒有也可以從原始碼用tarball的方式導入,自己再加個dkms.conf就可以了.



原文網址:https://kknews.cc/code/x6ay3yo.html

2021-06-24

Ubuntu – TP-Link Archer T3U Plus USB adapter

 Cannot make this wireless adapter work on Ubuntu 20.04… please help.

I've tried this: TP-LINK Archer T3U not working in Ubuntu 18.04
and now lsusb sees the device, but still doesn't work.

lsusb:
Bus 002 Device 006: ID 2357:0138 TP-Link 802.11ac NIC

uname -r:
5.4.0-39-generic

Edit: It works on my other computer with Ubuntu 18.04 using T2U Plus driver from here: https://github.com/RinCat/RTL88x2BU-Linux-Driver

But it does not work with Ubuntu 20.04…

sudo modprobe 88x2bu: Gives nothing.

modinfo 88x2bu | grep -e version -e 0138 :

version:        v5.6.1_30362.20181109_COEX20180928-6a6a
srcversion:     9C5282368F93050B7206C8D
parm:           rtw_chip_version:int

dmesg | grep 88×2 :

[ 8087.334869] 88x2bu: loading out-of-tree module taints kernel.
[ 8087.336610] 88x2bu: module verification failed: signature and/or required key missing - tainting kernel
[ 8087.341389] usbcore: registered new interface driver rtl88x2bu

Best Answer

  • Please notice at the git repository that you linked:

    enter image description here

    Your son is evidently using the latest (5 or less days ago) version and you are not.

    Since dkms status returned nothing, we conclude that you installed with sudo make install. Let's remove the inoperative driver, update it and reinstall:

    cd ~/RTL88x2BU-Linux-Driver/
    sudo make uninstall
    make clean
    git pull
    make
    sudo make install
    sudo modprobe 88x2bu
    

    After each kernel update, you must recompile:

    cd ~/RTL88x2BU-Linux-Driver/
    make clean
    git pull
    make
    sudo make install
    sudo modprobe 88x2bu
    

    EDIT: As we have seen, the git pull step was ineffective as you downloaded the zip file rather than obtaining the driver by git clone.

    Please do:

    cd ~/RTL88x2BU-Linux-Driver-master
    

    Or whatever the name of the previously downloaded and extracted driver file is. Next:

    sudo make uninstall
    cd ..
    sudo rm -r RTL88x2BU-Linux-Driver-master
    

    Now. we'll download a fresh copy with updates that drive your device. With a temporary working internet connection, please do:

    wget https://github.com/RinCat/RTL88x2BU-Linux-Driver/archive/master.zip
    unzip master.zip
    cd RTL88x2BU-Linux-Driver-master
    make
    sudo make install
    sudo modprobe 88x2bu