如何在基于 Busybox 的最小系统的 init 中加载当前硬件的内核模块

如何在基于 Busybox 的最小系统的 init 中加载当前硬件的内核模块

在最低限度内忙碌盒基于 Linux 系统,必须在脚本中调用哪些命令init以确保加载当前硬件的所有内核模块?

答案1

根据硬件的不同,会有一些调用总线加载模块。其中大部分应该已经自动化。我假设通过 初始化文件系统,udev/mdev,哈尔德,初始化系统, 等等 ...

手动加载模块的一种方法是调用modprobe它将处理所有依赖项。

例如:

# 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 的二进制哈希版本。

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

添加

在指出之后我应该解释这一切背后的魔力。我必须尝试,但它有点粗略。

让我们看一下我的一个 GPU。

以下示例显示了莫代利亚斯我的 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

英伟达文件夹可以是任何模块名称之一,例如我可以给它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 模块只能在启动时加载。

答案2

在深入研究之后,假设一个最小的 initramfs ,其中一些驱动程序内置于内核中,其他驱动程序作为内核模块以及所有相关depmod生成的元数据出现,以下是我发现的内容:

内置于内核中的驱动程序在/init调用之前加载。

/init作为模块构建的驱动程序必须按如下方式加载:

  • 首先/sys并且/proc必须安装
  • 然后应该扫描现有的硬件并加载相关的内核模块

硬件扫描和模块加载通常应该通过一个简单的程序来完成mdev -s调用

不幸的是没有发挥应有的作用。因此,必须通过调用来强制这一过程发生find /sys/ -name modalias | xargs sort -u | xargs -n 1 modprobe

之后,当前硬件的所有驱动程序(及其依赖项)都将被加载并初始化。

相关内容