【Ubuntu】depmod之所有选项
azurekiln 发布于 阅读:66 Linux操作系统基础
那么今天要和大家讲的是depmod
这个程序,首先depmod
的名字是 dependency module
的缩写。在Linux中,它的核心工作是分析系统中所有的内核模块,并创建一个依赖关系映射文件。
那么现在我们通过help选项 (1/13) 来列出depmod
的帮助文档,我们输入
depmod --help
按回车,我们可以看到主要options这里除了最后两个选项外共有8个选项,还有3个附加选项。
我们先来看主选项中的倒数第二个选项,这是一个打印当前depmod
程序版本号信息的选项。
(2/13) 我们输入
depmod --version
然后回车运行,可以看到当前depmod
的版本号为 15。
接下来我们先来看第一个选项, Probe all modules
意思是分析所有模块。
第二个选项,Only does the work if there's a new module
,意思是只有在有新模块的情况下才能工作,也叫快速模式。、当添加-A
这个选项时,depmod
会比较模块文件的时间戳和现有依赖文件的时间戳。只有当它发现有新的模块,或者模块文件比依赖文件更新时,它才会去更新依赖关系。这比 -a
速度更快,适合在不确定是否有变化时运行。
第三个选项,Report not supplied symbols
,意思为报告缺失的符号。如果模块 A 说它需要一个叫 function_X
的功能/符号,但 depmod
扫描了所有其他模块后,发现没有一个模块能提供 function_X
,它就会输出“未满足的依赖”的报告消息。
第四个选项,Write the dependency file on stdout only
,意思为仅在stdout
上写入依赖文件,它会完成所有的分析工作,但不会写入任何文件,而是把本应写入 modules.dep
文件的内容直接打印到你的当前的终端上。这在调试或学习时非常安全。
第五个选项,Architecture symbol prefix
,意思为架构符号前缀,在某些非常特殊的交叉编译场景下,目标架构的符号可能带有一个特定的前缀(比如一个下划线 _
)。这是主要面向为老旧或非主流嵌入式系统进行交叉编译的开发者给出的保留选项,在实际场景下极少使用,添加这个选项你可以指定一个前缀,以便 depmod
在匹配符号时能够正确处理。
第六个选项,Read configuration from PATH
,意思为从路径中读取配置,默认情况下,depmod
会读取系统默认目录(/etc/depmod.d/
)下的配置文件和 主配置文件(/etc/depmod.conf
)。这些文件定义一些规则,比如模块的别名、软依赖等。而添加了-C
这个选项就是告诉 depmod
:“不要看系统默认的配置文件了,现在来看我指定的这个路径作为你的配置文件或配置目录。”
第七个选项,Enable verbose mode
,意思为启用详细模式,添加该选项,执行后会打印出它正在处理的每个模块的名字。
第八个选项,Warn on duplicates
,意思为当遇到重复时发出警告,添加该选项后,发现有两个不同的模块提供了同一个功能/符号时,就会发出警告。这表示模块可能发生冲突。
附加选项一,Use an image of a module tree
,意思为使用一个模块树的镜像。添加该选项,它将告诉 depmod
,不要在真实的根目录(/
)下工作,而是把指定的 DIR 目录当作临时的、虚拟的根目录。所有的模块扫描和文件写入都将在这个 DIR 内部进行,与你的真实系统完全隔离。
附加选项二,Use the file instead of the current kernel symbols
,意思为使用该文件而不是当前的内核符号,depmod
需要知道内核里有哪些可用的“功能”,即符号(Symbols)。默认情况下,它会尝试从当前正在运行的内核的 System.map
文件(通常在 /boot/
或 /proc/kallsyms
)中获取这个列表。添加了-F
选项就是要告诉 depmod
:“别看当前系统的符号表了,我给你一个文件,这里面有你需要的全部内核符号信息。”
附加选项三,Use Module.symvers file to check symbol versions
,意思为使用Module.symvers
文件检查符号版本,为了防止应用程序二进制接口ABI
被破坏,Linux 内核会对导出的符号进行版本控制。每个符号都有一个 CRC
校验和。当编译一个内核模块时,它会记录下它所依赖的每个内核符号的版本信息。depmod
在检查依赖时,也会检查版本是否匹配。而添加了-E
选项则是告诉 depmod
:“不要用当前内核的符号版本信息了,请用我指定的这个文件(通常是 Module.symvers
文件)来做版本校验。”
那么以上涉及到对操作系统的操作,我们的命令都需要在管理员权限一下,所以我们在执行之前我们需要在命令最前面添加sudo
以提升到管理员权限。
首先我们获取一下内核版本号并设置成变量,打印验证变量是否设置正确。
K_VER=$(uname -r)
echo "kernel version: $K_VER"
按回车后输出类似以下内核版本信息,说明内核版本信息获取成功。可以看到我们当前的内核版本为4.4.0。
现在我们先列出模块的文件信息。
ls -l /lib/modules/$K_VER/
我们记住这些modules开头的文件时间,(3/13) 然后我们输入
sudo depmod -a
回车后可以看到并没有任何输出内容, (4/13) 我们添加 -v 以启用详细模式。
sudo depmod -v -a
我们可以看到depmod
分析了所有内核模块符号依赖关系逐个并列了出来。
(5/13) 接着我们把-a
改为-A
再次执行。
sudo depmod -v -A
可以看到这次并没有输出,说明它没有发现任何需要更新的模块依赖关系,属于正常情况。
然后我们再次列出模块的模块的文件信息。我们输入
ls -l /lib/modules/$K_VER/
可以看到文件的修改时间发生改变。
我们再次记住这个文件修改时间,(6/13) 我们在原来的基础上添加-n
选项。
sudo depmod -v -a -n
等待执行完毕之后我们再次列出模块的模块的文件信息。我们输入
ls -l /lib/modules/$K_VER/
回车,可以看到文件修改时间并没有改变。
说明-n
选项不添加后会重新生成/lib/modules/$K_VER/
下的所有模块缓存文件。
(7/13) 接下来我们在语句添加-w
,用于检查是否有重复符号,我们输入
sudo depmod -w -a
然后回车,如果没有重复符号则不会打印任何信息。可以看到下图存在重复符号,一一以警告的形式被打印出来。
接下来我们在用户目录下创建一个沙箱总目录,我们输入
mkdir -p ~/mysandbox/rootfs/lib/modules/$K_VER
然后我们再把原系统有的两个模块复制到我们的沙箱中,这里以hid
、hid_generic
为例,我们先获取文件路径
A_PATH=$(modinfo -n hid_generic)
B_PATH=$(modinfo -n hid)
然后以echo的形式将路径打印出来。
echo "$A_PATH $B_PATH"
可以看到两个文件的路径都被正常打印,接下来我们将这两个文件复制到我们的沙箱中。
cp "$A_PATH" "$B_PATH" ~/mysandbox/rootfs/lib/modules/$K_VER
接下来我们可以通过ls
ls ~/mysandbox/rootfs/lib/modules/$K_VER
列出所有内核模块文件。
由于 hid_generic
模块通常依赖于 hid
模块。我们再来创建一个模块文件夹。
mkdir -p ~/mysandbox/bk_rootfs/lib/modules/$K_VER
创建完成后我们将模块A复制到我们新建好的模拟损坏的模块文件夹中。
cp "$A_PATH" ~/mysandbox/bk_rootfs/lib/modules/$K_VER
现在我们来创建配置文件目录。
mkdir -p ~/mysandbox/configs
创建后我们再来创建内核信息输出目录。
mkdir -p ~/mysandbox/kernel_output
然后我们从当前系统复制一份System.map
(符号表) 到我们的沙箱中。
sudo cp /boot/System.map-$(uname -r) ~/mysandbox/kernel_output/System.map-test
我们再从系统复制一份 Module.symvers
(符号版本) 到我们的沙箱中。
sudo cp /lib/modules/$(uname -r)/build/Module.symvers ~/mysandbox/kernel_output/Module.symvers-test
如图所示:
然后接下来我们来执行带-e
(8/13) 的选项来检查缺失的符号,我们添加-e
选项我们还需要添加-E
(9/13) 、-F
(10/13) 选项,我们还要添加-b
(11/13) 来指定模块文件夹,我们先来传入完好的模块文件夹。我们输入
sudo depmod -n -e -v -b ~/mysandbox/rootfs \
-E ~/mysandbox/kernel_output/Module.symvers-test \
-F ~/mysandbox/kernel_output/System.map-test \
$K_VER
我们可以看到
alias symbol:xxxxxxx hid
所有符号一一对应,并且所有符号都依赖于hid.ko
。
然后我们传入残缺的模块文件夹,我们输入
sudo depmod -n -e -v -b ~/mysandbox/bk_rootfs \
-E ~/mysandbox/kernel_output/Module.symvers-test \
-F ~/mysandbox/kernel_output/System.map-test \
$K_VER
可以看到这里因为缺失了hid.ko
,所以报错未知符号。
然后我们再来随意创建一个配置文件。
echo 'exclude deprecated' > ~/mysandbox/configs/mo.conf
然后使用cat
读取配置文件,检查配置文件是否正常。
cat ~/mysandbox/configs/mo.conf
创建完成后我们添加-C
选项 (12/13) 指定配置文件后再次执行。
sudo depmod -v -a -C ~/mysandbox/configs/mo.conf -b ~/mysandbox/rootfs $K_VER
我们可以看到第一行这里报错,说明-C
选项自定义配置文件是生效的。
最后关于这个-P
选项 (13/13),我们可以指定前缀为_
的进行处理 。
sudo depmod -n -v -P _ -a $K_VER
输入后回车执行处理,我们在上文也提到,这个选项主要面向为老旧或非主流嵌入式系统进行交叉编译的开发者给出的保留选项,在实际场景下极少使用,这里就不做过多赘述。
那么以上就是关于depmod
的所有选项介绍。