2025-02-17
在写函数的时候,为了控制内部的运行逻辑或者对内部进行初始化,一般都会给函数传入参数。同样的为了控制内核驱动的行为,我们也希望在驱动加载的时候给它传入初始化参数。通过不同的参数达到不同的初始状态,提高内核驱动的灵活性。
内核驱动模块参数支持的类型:
invbool一个布尔型. 颠倒了值, 所以真值变成false, 反之亦然.charp一个字符指针值. 内存为用户提供的字串分配, 指针因此设置.下面分别定义了三个不同类型的参数:
static char *whom = "world";
static int howmany = 1;
static int arr[3];
module_param(howmany, int, S_IRUGO);
module_param(whom, charp, S_IRUGO);
module_param_array(arr, int, NULL, S_IRUGO);
module_param宏将变量和参数关联起来。第三个参数是设置参数权限。在内核中的定义如下:
#define S_IRWXUGO	(S_IRWXU|S_IRWXG|S_IRWXO)
#define S_IALLUGO	(S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
#define S_IRUGO		(S_IRUSR|S_IRGRP|S_IROTH)
#define S_IWUGO		(S_IWUSR|S_IWGRP|S_IWOTH)
#define S_IXUGO		(S_IXUSR|S_IXGRP|S_IXOTH)
S_IRWXUGO: 表示用户(User)、组(Group)和其他用户(Other)的所有权限(读、写、执行)。
S_IRWXU:用户(User)的读、写、执行权限。S_IRWXG:组(Group)的读、写、执行权限。S_IRWXO:其他用户(Other)的读、写、执行权限。S_IALLUGO: 表示特殊权限位和用户、组、其他用户的所有权限。
S_ISUID:设置用户ID(SUID)位,允许用户以文件所有者的权限执行文件。S_ISGID:设置组ID(SGID)位,允许用户以文件所属组的权限执行文件,或在目录中创建的文件继承目录的组ID。S_ISVTX:粘滞位(Sticky bit),通常用于目录,允许只有文件所有者或root用户才能删除或重命名文件。S_IRWXUGO:用户、组和其他用户的所有权限S_IRUGO: 表示用户、组和其他用户都拥有读权限。
S_IRUSR:用户(User)的读权限。S_IRGRP:组(Group)的读权限。S_IROTH:其他用户(Other)的读权限。S_IWUGO: 表示用户、组和其他用户都拥有写权限。
S_IWUSR:用户(User)的写权限。S_IWGRP:组(Group)的写权限。S_IWOTH:其他用户(Other)的写权限。S_IXUGO: 表示用户、组和其他用户都拥有执行权限。
S_IXUSR:用户(User)的执行权限。S_IXGRP:组(Group)的执行权限。S_IXOTH:其他用户(Other)的执行权限。// parameters.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
static char *whom = "world";
static int howmany = 1;
static int arr[3];
module_param(howmany, int, S_IRUGO);
module_param(whom, charp, S_IRUGO);
module_param_array(arr, int, NULL, S_IRUGO);
static int __init parameters_init(void) {
    for (int i = 0; i < howmany; i++) {
        printk(KERN_INFO "hi, %s\n", whom);
    }
    for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
        printk(KERN_INFO "arr[%d] = %d\n", i, arr[i]);
    }
    return 0;
}
static void __exit parameters_exit(void) {
    printk(KERN_INFO "Goodbye, parameters module!\n");
}
module_init(parameters_init);
module_exit(parameters_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("heng30");
MODULE_VERSION("v0.0.1");
MODULE_DESCRIPTION("A simple parameters kernel module");
#!/bin/sh
arch = x86
top-dir = $(shell pwd)
kernel-version = $(shell uname -r)
kernel-dir ?= /lib/modules/$(kernel-version)/build
obj-m = parameters.o
target = parameters.ko
all:
	make -C $(kernel-dir) modules M=$(top-dir)
install:
	insmod $(target) howmany=3 whom="blue" arr=1,2,3
uninstall:
	rmmod $(target)
info:
	modinfo $(target)
clean:
	rm -f *.o *.ko *.mod *.mod.c *.order *.symvers
	make -C $(kernel-dir) clean m=$(top-dir)
dmesg:
	dmesg
传入的参数为howmany=3 whom="blue" arr=1,2,3。运行make install加载驱动。加载成功后,运行make dmesg查看输出信息。