作者 | David Clinton
譯者 | amwps290 ? ? 共計翻譯:12 篇 貢獻時間:133 天
找到並裝載核心模組以解決外設問題。
本文來自 Manning 出版的 Linux in Action[1] 的第 15 章。
Linux 使用核心模組管理硬體外設。 我們來看看它是如何工作的。
執行中的 Linux 內核是您不希望被破壞的東西之一。畢竟,內核是驅動計算機所做的一切工作的軟體。考慮到在一個執行的系統上必須同時管理諸多細節,最好能讓核心盡可能的減少分心,專心的完成它的工作。但是,如果對計算環境進行任何微小的更改都需要重啟整個系統,那麼插入一個新的網路攝像頭或印表機就可能會嚴重影響您的工作流程。每次新增裝置時都必須重新啟動,以使系統識別它,這效率很低。
為了在穩定性和可用性之間達成有效的平衡,Linux 將核心隔離,但是允許您透過可載入核心模組 (LKM) 實時新增特定的功能。如下圖所示,您可以將模組視為軟體的一部分,它告訴核心在哪裡找到一個裝置以及如何使用它。反過來,核心使裝置對使用者和行程可用,並監視其操作。
核心模組充當裝置和 Linux 核心之間的轉換器。
雖然你可以自己編寫模組來完全按照你喜歡的方式來支援一個裝置,但是為什麼要這樣做呢?Linux 模組庫已經非常強大,通常不需要自己去實現一個模組。 而絕大多數時候,Linux 會自動載入新裝置的模組,而您甚至不知道它。
不過,有時候,出於某種原因,它本身並不會自動進行。(你肯定不想讓那個招聘經理不耐煩地一直等待你的笑臉加入影片面試。)為了幫助你解決問題,你需要更多地瞭解核心模組,特別是,如何找到執行你的外設的實際模組,然後如何手動啟用它。
查詢核心模組
按照公認的約定,核心模組是位於 /lib/modules/
目錄下的具有 .ko(核心物件)副檔名的檔案。 然而,在你找到這些檔案之前,你還需要選擇一下。因為在引導時你需要從版本串列中選擇其一載入,所以支援您選擇的特定軟體(包括核心模組)必須存在某處。 那麼,/lib/modules/
就是其中之一。 你會發現目錄裡充滿了每個可用的 Linux 核心版本的模組; 例如:
$ ls /lib/modules
4.4.0-101-generic
4.4.0-103-generic
4.4.0-104-generic
在我的電腦上,執行的內核是版本號最高的版本(4.4.0-104-generic),但不能保證這對你來說是一樣的(核心經常更新)。 如果您將要在一個執行的系統上使用模組完成一些工作的話,你需要確保您找到正確的目錄樹。
好訊息:有一個可靠的竅門。相對於透過名稱來識別目錄,並希望能夠找到正確的目錄,你可以使用始終指向使用的核心名稱的系統變數。 您可以使用 uname -r
( -r
從系統資訊中指定通常顯示的核心版本號)來呼叫該變數:
$ uname -r
4.4.0-104-generic
透過這些資訊,您可以使用稱為命令替換的過程將 uname
併入您的檔案系統取用中。 例如,要導航到正確的目錄,您需要將其新增到 /lib/modules
。 要告訴 Linux “uname” 不是一個檔案系統中的位置,請將 uname
部分用反引號括起來,如下所示:
$ ls /lib/modules/`uname -r`
build modules.alias modules.dep modules.softdep
initrd modules.alias.bin modules.dep.bin modules.symbols
kernel modules.builtin modules.devname modules.symbols.bin
misc modules.builtin.bin modules.order vdso
你可以在 kernel/
目錄下的子目錄中找到大部分模組。 花幾分鐘時間瀏覽這些目錄,瞭解事物的排列方式和可用內容。 這些檔案名通常會讓你知道它們是什麼。
$ ls /lib/modules/`uname -r`/kernel
arch crypto drivers fs kernel lib mm
net sound ubuntu virt zfs
這是查詢核心模組的一種方法;實際上,這是一種快速的方式。 但這不是唯一的方法。 如果你想獲得完整的集合,你可以使用 lsmod
列出所有當前載入的模組以及一些基本資訊。 這個截斷輸出的第一列(在這裡列出的太多了)是模組名稱,後面是檔案大小和數量,然後是每個模組的名稱:
$ lsmod
[...]
vboxdrv 454656 3 vboxnetadp,vboxnetflt,vboxpci
rt2x00usb 24576 1 rt2800usb
rt2800lib 94208 1 rt2800usb
[...]
到底有多少?好吧,我們再執行一次 lsmod
,但是這一次將輸出管道輸送到 wc -l
看一下一共多少行:
$ lsmod | wc -l
113
這是已載入的模組。 總共有多少個? 執行 modprobe -c
並計算這些行將給我們這個數字:
$ modprobe -c | wc -l
33350
有 33,350 個可用模組!? 看起來好像有人多年來一直在努力為我們提供軟體來驅動我們的物理裝置。
註意:在某些系統中,您可能會遇到自定義的模組,這些模組要麼在 /etc/modules
檔案中使用獨特的條目進行取用,要麼在 /etc/modules-load.d/
下的配置檔案中。這些模組很可能是本地開發專案的產物,可能涉及前沿實驗。不管怎樣,知道你看到的是什麼總是好的。
這就是如何找到模組的方法。 如果出於某種原因,它不會自行載入,您的下一個工作就是弄清楚如何手動載入未啟用的模組。
手動載入核心模組
在載入核心模組之前,邏輯上您必須確認它存在。在這之前,你需要知道它叫什麼。要做到這一點,有時需要兼有魔法和運氣以及線上檔案作者的辛勤工作的幫助。
我將透過描述一段時間前遇到的問題來說明這個過程。在一個晴朗的日子裡,出於某種原因,膝上型電腦上的 WiFi 介面停止工作了。就這樣。也許是軟體升級把它搞砸了。誰知道呢?我運行了 lshw -c network
,得到了這個非常奇怪的資訊:
network UNCLAIMED
AR9485 Wireless Network Adapter
Linux 識別到了介面(Atheros AR9485),但將其列為未宣告。 那麼,正如他們所說的那樣,“當情況變得嚴峻時,就會在網際網路上進行艱難的搜尋。” 我搜索了一下 atheros ar9 linux 模組,在瀏覽了一頁又一頁五年前甚至是十年前的頁面後,它們建議我自己寫個模組或者放棄吧,然後我終於發現(最起碼 Ubuntu 16.04)有一個可以工作的模組。 它的名字是 ath9k 。
是的! 這場戰鬥勝券在握!向內核新增模組比聽起來容易得多。 要仔細檢查它是否可用,可以針對模組的目錄樹執行 find
,指定 -type f
來告訴 Linux 您正在查詢檔案,然後將字串 ath9k
和星號一起新增以包含所有以你的字串打頭的檔案:
$ find /lib/modules/$(uname -r) -type f -name ath9k*
/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_common.ko
/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k.ko
/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_htc.ko
/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_hw.ko
再一步,載入模組:
# modprobe ath9k
就是這樣。無啟動,沒煩惱。
這裡還有一個示例,向您展示如何使用已經崩潰的執行模組。曾經有一段時間,我使用羅技網路攝像頭和一個特定的軟體會使攝像頭在下次系統啟動前無法被任何其他程式訪問。有時我需要在不同的應用程式中開啟相機,但沒有時間關機重新啟動。(我運行了很多應用程式,在引導之後將它們全部準備好需要一些時間。)
由於這個模組可能是執行的,所以使用 lsmod
來搜尋 video 這個詞應該給我一個關於相關模組名稱的提示。 實際上,它比提示更好:用 video 這個詞描述的唯一模組是 uvcvideo(如下所示):
$ lsmod | grep video
uvcvideo 90112 0
videobuf2_vmalloc 16384 1 uvcvideo
videobuf2_v4l2 28672 1 uvcvideo
videobuf2_core 36864 2 uvcvideo,videobuf2_v4l2
videodev 176128 4 uvcvideo,v4l2_common,videobuf2_core,videobuf2_v4l2
media 24576 2 uvcvideo,videodev
有可能是我自己的操作導致了崩潰,我想我可以挖掘更深一點,看看我能否以正確的方式解決問題。但結果你知道的;有時你不關心理論,只想讓裝置工作。 所以我用 rmmod
殺死了 uvcvideo
模組,然後用 modprobe
重新啟動它,一切都好:
# rmmod uvcvideo
# modprobe uvcvideo
再一次:不重新啟動。沒有其他的後續影響。
via: https://opensource.com/article/18/5/how-load-or-unload-linux-kernel-module
作者:David Clinton[3] 選題:lujun9972 譯者:amwps290 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出