00. 目录
01. 概述
我们如愿编译了自己的内核模块,接下来就该了解如何使用这个内核模块了。 将test.ko通过scp或NFS拷贝到开发板中,我们来逐一讲解这些内核模块相关工具。
02. insmod
BusyBox v1.27.2 (2023-08-17 12:27:26 CST) multi-call binary.
Usage: insmod FILE [SYMBOL=VALUE]...
Load kernel module
应用示例:
[root@rk3399:/mnt/a72/code/1module]# insmod test.ko
[16933.818461] Hello Module Init
[root@rk3399:/mnt/a72/code/1module]#
calculation.ko依赖parametermodule.ko中的参数和函数, 所以先手动加载parametermodule.ko,然后再加载calculation.ko。
modprobe和insmod具备同样的功能,同样可以将模块加载到内核中,除此以外modprobe还能检查模块之间的依赖关系, 并且按照顺序加载这些依赖,可以理解为按照顺序多次执行insmod。
calculation.ko和parametermodule.ko需要按照先后次序依次加载,而使用modprobe工具, 可以直接加载parametermodule.ko,当然modprobe之前需要先用depmod -a建立模块之间的依赖关系。 (注意: 使用 depmod -a
命令建立依赖关系之需要把calculation.ko和parametermodule.ko复制到 /lib/modules/内核版本
目录下;此外在使用 modprobe
加载驱动时,驱动名不带 .ko
, 否则会出现如下错误 modprobe: FATAL: Module calculation.ko not found in directory /lib/modules/4.19.35-imx6
, 卸载驱动时也一样)
03. lsmod
BusyBox v1.27.2 (2023-08-17 12:27:26 CST) multi-call binary.
Usage: lsmod
List loaded kernel modules
lsmod列出当前内核中的所有模块,格式化显示在终端,其原理就是将/proc/modules中的信息调整一下格式输出。 lsmod输出列表有一列 Used by, 它表明此模块正在被其他模块使用,显示了模块之间的依赖关系。
如果要将一个模块加载到内核中,insmod是最简单的办法, insmod+模块完整路径就能达到目的,前提是你的模块不依赖其他模块,还要注意需要sudo权限。 如果你不确定是否使用到其他模块的符号,你也可以尝试modprobe,后面会有它的详细用法。
通过insmod命令加载test.ko内存模块加载该内存模块的时候, 该内存模块会自动执行module_init()函数,进行初始化操作,该函数打印了 ‘hello module init’。 再次查看已载入系统的内核模块,我们就会在列表中发现test.ko的身影。
应用示例
[root@rk3399:/mnt/a72/code/1module]# lsmod
Module Size Used by Tainted: G
test 16384 0
[root@rk3399:/mnt/a72/code/1module]#
04. depmod
Usage:
depmod -[aA] [options] [forced_version]
If no arguments (except options) are given, "depmod -a" is assumed
depmod will output a dependency list suitable for the modprobe utility.
Options:
-a, --all Probe all modules
-A, --quick Only does the work if there's a new module
-e, --errsyms Report not supplied symbols
-n, --show Write the dependency file on stdout only
-P, --symbol-prefix Architecture symbol prefix
-C, --config=PATH Read configuration from PATH
-v, --verbose Enable verbose mode
-w, --warn Warn on duplicates
-V, --version show version
-h, --help show this help
The following options are useful for people managing distributions:
-b, --basedir=DIR Use an image of a module tree.
-F, --filesyms=FILE Use the file instead of the
current kernel symbols.
-E, --symvers=FILE Use Module.symvers file to check
symbol versions.
deng@local:~/a72/x3399/kernel/include/linux$
modprobe是怎么知道一个给定模块所依赖的其他的模块呢?在这个过程中,depend起到了决定性作用,当执行modprobe时, 它会在模块的安装目录下搜索module.dep文件,这是depmod创建的模块依赖关系的文件。
05. rmmod
Usage:
rmmod [options] modulename ...
Options:
-f, --force forces a module unload and may crash your
machine. This requires Forced Module Removal
option in your kernel. DANGEROUS
-s, --syslog print to syslog, not stderr
-v, --verbose enables more messages
-V, --version show version
-h, --help show this help
deng@local:~/a72/x3399/kernel/include/linux$
rmmod工具仅仅是将内核中运行的模块删除,只需要传给它路径就能实现。
rmmod命令卸载某个内存模块时,内存模块会自动执行*_exit()函数,进行清理操作, 我们的hellomodule中的*_exit()函数打印了一行内容,但是控制台并没有显示,可以使用dmesg查看, 之所以没有显示是与printk的打印等级有关,前面有关于printk函数有详细讲解。 rmmod不会卸载一个模块所依赖的模块,需要依次卸载,当然是用modprobe -r 可以一键卸载。
应用示例:
[root@rk3399:/mnt/a72/code/1module]# rmmod test
[17225.438774] Hello Module Exit
[root@rk3399:/mnt/a72/code/1module]#
06. modinfo
Usage:
modinfo [options] filename [args]
Options:
-a, --author Print only 'author'
-d, --description Print only 'description'
-l, --license Print only 'license'
-p, --parameters Print only 'parm'
-n, --filename Print only 'filename'
-0, --null Use \0 instead of \n
-F, --field=FIELD Print only provided FIELD
-k, --set-version=VERSION Use VERSION instead of `uname -r`
-b, --basedir=DIR Use DIR as filesystem root for /lib/modules
-V, --version Show version
-h, --help Show this help
deng@local:~/a72/x3399/kernel/include/linux$
modinfo用来显示我们在内核模块中定义的几个宏。 我们可以通过modinfo来查看,我们从打印的输出信息中,可以了解到,该模块遵循的是GPL协议, 该模块的作者信息等。而这些信息在模块代码中由相关内核模块信息声明函数声明
deng@local:~/code/test/1module$ modinfo test.ko
filename: /home/deng/a72/code/1module/test.ko
alias: test_module
description: hello module
author: uplooking
license: GPL v2
depends:
vermagic: 4.4.189 SMP mod_unload aarch64
deng@local:~/code/test/1module$
07. 系统自动加载模块
我们自己编写了一个模块,或者说怎样让它在板子开机自动加载呢? 这里就需要用到上述的depmod和modprobe工具了。
首先需要将我们想要自动加载的模块统一放到”/lib/modules/内核版本”目录下,内核版本使用’uname -r’查询; 其次使用depmod建立模块之间的依赖关系,命令’ depmod -a’; 这个时候我们就可以在modules.dep中看到模块依赖关系,可以使用如下命令查看;
cat /lib/modules/内核版本/modules.dep | grep calculation
最后在/etc/modules加上我们自己的模块,注意在该配置文件中,模块不写成.ko形式代表该模块与内核紧耦合,有些是系统必须要跟内核紧耦合,比如mm子系统, 一般写成.ko形式比较好,如果出现错误不会导致内核出现panic错误,如果集成到内核,出错了就会出现panic。
deng@local:~/a72/x3399/kernel/include/linux$ cat /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
然后重启开发板,lsmod就能查看到我们的模块开机就被加载到内核里面了。