在Linux内核模块编程中,`module_param`宏允许你声明一个模块参数。模块参数是指可以在加载模块时从命令行设置的参数,也可以通过/sys文件系统(如果内核配置了CONFIG_SYSFS)在模块加载后进行修改。这些参数对于调整模块的行为而不需要重新编译模块代码非常有用。
使用方法
`module_param`宏的基本语法如下:
module_param(name, type, perm);
- `name`: 参数的名称,这将是加载模块时使用的名称。
- `type`: 参数的数据类型,决定了参数可以接受的数据类型(例如,int、bool、charp等)。
- `perm`: 参数在sysfs文件系统中的权限(如果使用),通常是使用标准的Linux权限宏(如S_IRUGO和S_IWUSR)。
示例
让我们通过一个具体的例子来演示如何在Linux内核模块中使用`module_param`宏。我们将创建一个简单的模块,该模块接受一个整数参数和一个字符串参数。这个模块在加载时会打印这些参数的值,以演示如何从命令行传递参数给模块。
步骤 1: 编写模块代码
首先,创建一个名为`example_module.c`的文件,并添加以下代码:```c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
// 定义模块参数变量
static int int_param = 1;
static char *str_param = "default";
// 声明模块参数
module_param(int_param, int, S_IRUGO);
module_param(str_param, charp, S_IRUGO);
MODULE_PARM_DESC(int_param, "An integer parameter");
MODULE_PARM_DESC(str_param, "A string parameter");
// 模块加载函数
static int __init example_module_init(void) {
printk(KERN_INFO "Example Module Loaded!\n");
printk(KERN_INFO "Integer parameter: %d\n", int_param);
printk(KERN_INFO "String parameter: %s\n", str_param);
return 0; // 返回0表示加载成功
}
// 模块卸载函数
static void __exit example_module_exit(void) {
printk(KERN_INFO "Example Module Unloaded!\n");
}
// 指定加载和卸载函数
module_init(example_module_init);
module_exit(example_module_exit);
// 模块许可证和作者信息
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple example Linux module.");
步骤 2: 编写Makefile创建一个Makefile来编译模块:
obj-m += example_module.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
步骤 3: 编译模块
在终端中运行`make`命令来编译模块:
步骤 4: 加载模块
使用`insmod`命令加载模块,并传递参数:
sudo insmod example_module.ko int_param=42 str_param="Hello, world!"
步骤 5: 检查输出
检查`dmesg`的输出来确认模块正确加载并打印了参数值:
dmesg | tail
你应该会看到类似以下的输出:
[...] Example Module Loaded!
[...] Integer parameter: 42
[...] String parameter: Hello, world!
步骤 6: 卸载模块
最后,使用`rmmod`命令卸载模块:
sudo rmmod example_module
再次检查`dmesg`的输出来确认模块已被卸载:
dmesg | tail
这个简单的例子展示了如何使用`module_param`宏来接受来自命令行的参数,并在模块加载时使用这些参数。
如果内核配置了sysfs,并且模块已经加载,你还可以通过下面的命令来动态改变参数:
echo 20 > /sys/module/mymodule/parameters/int_param
echo "world" > /sys/module/mymodule/parameters/str_param
注意事项
- 使用`module_param`时,你需要确保定义的变量具有全局作用域(即在函数外部定义),因为它们需要在模块加载时可用。
- 修改sysfs中的参数可能不会立即影响模块的行为,这取决于模块如何使用这些参数。有些参数可能需要重新加载模块才能生效。
- 使用`module_param`时,确保考虑到安全性和权限,特别是如果参数允许写操作。不恰当的权限可能会导致安全漏洞。