內核模塊

出自 Arch Linux 中文维基

內核模塊是可以按需加載或卸載的內核代碼,可以不重啟系統就擴充內核的功能。

要創建內核模塊,請閱讀此指南。模塊可以設置成內置或者可加載,要動態加載或刪除模塊,必須在內核配置中將其配置為可加載模塊(因此與模塊相關的行將顯示字母 M)。

如果您想在新內核安裝後自動重建模塊,參見 Dynamic Kernel Module Support(DKMS)。

獲取信息[編輯 | 編輯原始碼]

模塊保存在 /lib/modules/kernel_release (使用 uname -r 命令顯示當前內核版本)。

注意: 模塊名通常使用 (_) 或 - 連接,但是這些符號在 modprobe 命令和 /etc/modprobe.d/ 配置文件中都是可以相互替換的。

顯示當前裝入的內核模塊:

$ lsmod

顯示模塊信息:

$ modinfo module_name

顯示所有模塊的配置信息:

$ modprobe -c | less

顯示某個模塊的配置信息:

$ modprobe -c | grep module_name

顯示一個裝入模塊使用的選項,可以使用sysfsutils中的systool(1)

$ systool -v -m module_name

顯示模塊的依賴關係:

$ modprobe --show-depends module_name

自動加載模塊[編輯 | 編輯原始碼]

目前,所有必要模塊的加載均由 udev 自動完成。所以,如果不需要使用任何額外的模塊,就沒有必要在任何配置文件中添加啟動時加載的模塊。但是,有些情況下可能需要在系統啟動時加載某個額外的模塊,或者將某個模塊列入黑名單以便使系統正常運行。

systemd[編輯 | 編輯原始碼]

內核模塊可以在/etc/modules-load.d/ 下的文件中明確列出,以便 systemd 在引導過程中加載它們。 每個配置文件都以 /etc/modules-load.d/program.conf的樣式命名。 配置文件僅包含要加載的內核模塊名稱列表,以換行符分隔。 空行和第一個非空白字符為#;的行被忽略。

/etc/modules-load.d/virtio-net.conf
# Load virtio_net.ko at boot
virtio_net

另見modules-load.d(5)

早期模塊加載[編輯 | 編輯原始碼]

initramfs 映像可能不包含 /etc/modules-load.d/ 中要求的內核模塊,它也可能缺少在該文件夾中設置的文件。早期模塊加載取決於使用的 initramfs 生成器:

手動加載模塊[編輯 | 編輯原始碼]

內核模塊由 kmod 包提供的工具處理。您可以手動使用這些工具。

注意: 如果你已經升級了你的內核但還沒有重新啟動,modprobe 將失敗並且沒有錯誤消息並以代碼 1 退出,因為路徑 /usr/lib/modules/$(uname -r)/ 不再存在。當 modprobe 無法確定是否存在這種情況時,請手動檢查此路徑是否存在。

要手動裝入模塊的話,執行:

# modprobe module_name

按文件名加載模塊:

# insmod filename [args]

如果要移除一個模塊:

# modprobe -r module_name

或者:

# rmmod module_name

配置模塊參數[編輯 | 編輯原始碼]

要將參數傳遞給內核模塊,您可以使用 modprobe 手動傳遞它們,或者使用 modprobe 配置文件或使用內核命令行確保始終應用某些參數。如果該模塊內置於內核中,則必須使用內核命令行,其他方法將不起作用。

手動加載時設置[編輯 | 編輯原始碼]

將參數傳遞給模塊的基本方法是使用 modprobe 命令。使用簡單的 key=value 賦值在命令行上指定參數:

# modprobe module_name parameter_name=parameter_value

使用 /etc/modprobe.d/中的文件[編輯 | 編輯原始碼]

/etc/modprobe.d/ 目錄中的文件可用於將模塊設置傳遞給 udev,它將使用 modprobe 管理系統啟動期間的模塊加載.此目錄中的配置文件可以具有任何名稱,只要它們以 .conf 擴展名結尾。語法是:

/etc/modprobe.d/myfilename.conf
options module_name parameter_name=parameter_value

多個模塊參數用空格分隔,而一個參數可以接收一個值列表,列表用逗號分隔:

/etc/modprobe.d/myfilename.conf
options module_name param1=value1 param2=value2a,value2b …

例如:

/etc/modprobe.d/thinkfan.conf
# On ThinkPads, this lets the 'thinkfan' daemon control fan speed
options thinkpad_acpi fan_control=1
注意: 如果任何受影響的模塊是從 initramfs 加載的,那麼您需要將適當的 .conf 文件添加到 mkinitcpio.conf 中的 FILES 或使用modconf hook,然後 重新生成 initramfs 以包含「.conf」文件。要查看默認 initramfs 的內容,請使用 lsinitcpio

使用內核命令行[編輯 | 編輯原始碼]

還可以使用內核命令行向模塊傳遞選項。這也是向內核內置模塊傳遞選項的唯一途徑。對於所有常見的引導加載程序,以下語法是正確的:

modname.parametername=parametercontents

例如:

thinkpad_acpi.fan_control=1

只需將其添加到引導加載程序的內核行,如 內核參數 中所述。

別名[編輯 | 編輯原始碼]

別名是模塊的替代名稱。例如:alias my-mod real_long_modulename 表示您可以使用 modprobe my-mod 代替 modprobe real_long_modulename。您也可以使用 shell 風格的通配符,所以 alias my-mod* really_long_modulename 意味着 modprobe my-modmodprobe my-mod-something 有相同的效果。創建別名:

/etc/modprobe.d/myalias.conf
alias mymod really_long_module_name

一些模塊具有別名,用於在應用程序需要它們時自動加載它們。禁用這些別名可以防止自動加載,但仍允許手動加載模塊。

/etc/modprobe.d/modprobe.conf
# Prevent Bluetooth autoload
alias net-pf-31 off

黑名單[編輯 | 編輯原始碼]

在內核模塊的上下文中,黑名單是一種防止內核模塊加載的機制。如果不需要相關的硬件,或者如果加載該模塊會導致問題,這可能很有用:例如,可能有兩個內核模塊試圖控制同一個硬件,將它們一起加載會導致衝突。

一些模塊作為 initramfs 的一部分加載。 mkinitcpio -M 將打印出所有自動檢測到的模塊:為了防止 initramfs 加載其中一些模塊,請將它們列入黑名單中的 /etc/modprobe.d 下的 .conf 文件 並且它應該在圖像生成期間由 modconf 掛鈎添加。運行 mkinitcpio -v 將列出由各種掛鈎(例如 filesystems 掛鈎、block 掛鈎等)拉入的所有模塊。如果您的文件中沒有 modconf 掛鈎,請記住將該 .conf 文件添加到 /etc/mkinitcpio.conf 中的 FILES 列表中HOOKS 列表(比如您改變了默認配置),將模塊列入黑名單 regenerate the initramfs,然後重新啟動。

使用 /etc/modprobe.d/ 中的文件[編輯 | 編輯原始碼]

/etc/modprobe.d/ 中創建一個 .conf 文件,並使用 blacklist 關鍵字為要列入黑名單的每個模塊附加一行。例如,如果您想阻止 pcspkr 模塊加載以避免通過 PC 揚聲器 發出聲音:

/etc/modprobe.d/nobeep.conf
# Do not load the 'pcspkr' module on boot.
blacklist pcspkr
注意: blacklist 命令將一個模塊列入黑名單,這樣它就不會自動加載,但如果另一個未列入黑名單的模塊依賴於它或者它是手動加載的,則該模塊可能會被加載。

但是,對於該情況有一個解決方法; install 命令指示 modprobe 運行自定義命令,而不是像往常一樣將模塊插入內核,因此您可以強制使模塊加載失敗:

/etc/modprobe.d/blacklist.conf
...
install module_name /bin/true
...

這將有效地將該模塊和任何其他依賴於它的模塊列入黑名單。

使用內核命令行[編輯 | 編輯原始碼]

提示:如果模塊損壞導致無法引導系統,這將非常有用。

您也可以從引導加載程序中將模塊列入黑名單。

Kernel參數.中所述,只需將module_blacklist=modname1,modname2,modname3 添加到引導加載程序的內核行中即可。

注意:
  • 將多個模塊列入黑名單時,請注意,它們之間僅用逗號分隔。 空格或其他內容可能會破壞語法。
  • module_blacklist 會讓內核完全拒絕加載模塊。如果只想阻止隱式加載,可能會在稍後手動加載模塊,那麼正確的參數是 modprobe.blacklist=modname1,modname2,modname3。這並不能阻止啟動過程中的顯式加載,例如通過 systemd 或其他模塊。

問題處理[編輯 | 編輯原始碼]

模塊未加載[編輯 | 編輯原始碼]

如果特定模塊未加載並且啟動日誌(可通過以 root 身份運行 journalctl -b 訪問)顯示該模塊已列入黑名單,但目錄 /etc/modprobe.d/ 沒有顯示相應的條目,請檢查 /usr/lib/modprobe.d/ 的另一個 modprobe 源目錄以獲取黑名單條目。

如果內核模塊中包含的「vermagic」字符串與當前運行的內核的值不匹配,則不會加載模塊。如果已知模塊與當前運行的內核兼容,則可以使用 modprobe --force-vermagic 忽略「vermagic」檢查。

警告: 忽略內核模塊的版本檢查可能會導致內核崩潰或系統由於不兼容而表現出未定義的錯誤。請謹慎使用 --force-vermagic

參見[編輯 | 編輯原始碼]