Linux

如何在基於 Busybox 的最小系統的 init 中載入目前硬體的核心模組

  • December 30, 2021

在基於Busybox的最小Linux 系統中,必須呼叫哪些命令作為init腳本的一部分以確保載入目前硬體的所有核心模組?

在進入兔子洞之後,假設一個最小的 initramfs,其中一些驅動程序內置在核心中,而其他驅動程序則作為核心模組以及所有相關depmod生成的元數據出現,這就是我發現的:

核心中內置的驅動程序在/init呼叫之前被載入。

建構為模組的驅動程序必須按/init以下方式載入:

  • 首先/sys並且/proc必須安裝
  • 然後應該掃描現有的硬體並載入相關的核心模組

硬體掃描和模組載入通常應該通過一個簡單的mdev -s呼叫來完成。

不幸的是,這不能正常工作。必須通過呼叫find /sys/ -name modalias | xargs sort -u | xargs -n 1 modprobe來強制執行此過程。

之後,目前硬體(及其依賴項)的所有驅動程序都將被載入和初始化。

根據硬體的不同,會有一些呼叫dbus來載入模組。其中大部分應該已經自動化。我假設通過 initramfsudev/mdevhaldinit-system等等……

手動載入模組的一種方法是呼叫modprobewhich 將處理所有依賴項。

例如:

# modprobe snd_pcm

在我的情況下,這將載入創建聲音所需的所有模組。

首先modprobe將載入所有依賴項snd_hda_core。這是原因snd_hda_core是一部分snd_pcm

$ lsmod | grep ^snd_hda_core 
snd_hda_core          110592  5 snd_hda_codec_generic,snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec,snd_hda_codec_realtek

之後,所有snd_pcm依賴項都由modprobe.

$ lsmod | grep ^snd_pcm
snd_pcm               135168  10 snd_hda_codec_hdmi,snd_hda_intel,snd_usb_audio,snd_hda_codec,soundwire_intel,snd_compress,snd_soc_core,snd_hda_core,snd_pcm_dmaengine

有一個名為的文件夾/etc/modules-load.d/,其中包含*.conf預設載入某些模組的文件。這應該可以滿足您的所有需求,因此無需編寫初始化腳本…

$ cat /etc/modules-load.d/local.conf 
vfio_pci
asus-wmi-sensors
tun

換句話說:我可以通過一個呼叫或一個文件載入所有模組。

modprobe 手冊頁 …

modprobe 需要一個最新的 modules.dep.bin 文件,該文件由與 modprobe 一起提供的相應 depmod 實用程序生成(請參閱 depmod(8))。該文件列出了每個模組需要的其他模組(如果有的話),modprobe 使用它來自動添加或刪除這些依賴項

depmod 手冊頁…

Linux 核心模組可以提供服務(稱為“符號”)供其他模組使用(使用程式碼中的 EXPORT_SYMBOL 變體之一)。如果第二個模組使用此符號,則該第二個模組顯然依賴於第一個模組。這些依賴關係可能會變得相當複雜。

depmod 通過讀取 /lib/modules/version 下的每個模組並確定它導出什麼符號以及它需要什麼符號來創建一個模組依賴項列表。預設情況下,此列表將寫入 modules.dep 和名為 modules.dep.bin 的二進制散列版本,位於同一目錄中。

#####################

添加

在指出我應該解釋這一切背後的魔力。我必須嘗試,但它有點粗略。

讓我們看看我的一個gpus。

以下範例顯示了我的 gpu的模態****別名和模組定義中的別名重疊。

$ lspci
...
0b:00.0 VGA compatible controller: NVIDIA Corporation GP102 [GeForce GTX 1080 Ti] (rev a1)
...
$ cat /sys/bus/pci/devices/0000:0b:00.0/modalias
pci:v000010DEd00001B06sv00001462sd00003607bc03sc00i00
$ modinfo nvidia
...
alias:          pci:v000010DEd*sv*sd*bc03sc02i00*
alias:          pci:v000010DEd*sv*sd*bc03sc00i00*
depends:        i2c-core,drm
...

lspci 手冊頁…

核心模組報告它能夠處理設備

這部分對我來說有點陌生,我不得不猜測一下。

無論如何,由於我現在收集的資訊,我知道根據這些資訊設置模組的兩種方法。

第一種方法(啟動時)…

echo "alias $(cat /sys/bus/pci/devices/0000:0b:00.0/modalias) nvidia" >> /etc/modprobe.d/default.conf 

第二種方法(執行時)…

echo "0000:0b:00.0" > /sys/bus/pci/drivers/nvidia/bind

nvidia文件夾可以是任何模組名稱之一,例如我可以給它vfio-pci文件夾。

echo "0000:0b:00.0" > /sys/bus/pci/drivers/nvidia/unbind
echo "0000:0b:00.0" > /sys/bus/pci/drivers/vfio-pci/bind

請記住,這只是一個範例,不能在真實環境中工作,因為 gpu 模組只能在啟動時載入。

引用自:https://unix.stackexchange.com/questions/683743