2. 模块参数传递
任务目标
为Android内核模块添加可配置参数,支持在加载时通过insmod或modprobe传递参数,并在模块加载/卸载时读取和显示参数值。
核心实现
本案例实现一个最小内核模块,定义三种典型参数类型:int、char*和int数组。模块加载时打印参数值,卸载时打印参数最终值,用于验证参数传递是否生效。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
/* 模块参数定义 */
static int count = 1;
static char *name = "android_drv";
static int arr[4] = {0, 0, 0, 0};
static int arr_argc = 0;
/* 参数注册:权限0644表示可通过sysfs在运行时查看/修改 */
module_param(count, int, 0644);
MODULE_PARM_DESC(count, "loop count, default 1");
module_param(name, charp, 0644);
MODULE_PARM_DESC(name, "device name, default android_drv");
/* 数组参数:arr_argc自动接收实际传入的元素个数 */
module_param_array(arr, int, &arr_argc, 0644);
MODULE_PARM_DESC(arr, "int array, max 4 elements");
static int __init param_demo_init(void)
{
int i;
pr_info("param_demo: module loaded\n");
pr_info("param_demo: count = %d\n", count);
pr_info("param_demo: name = %s\n", name);
pr_info("param_demo: arr_argc = %d\n", arr_argc);
for (i = 0; i < arr_argc; i++)
pr_info("param_demo: arr[%d] = %d\n", i, arr[i]);
return 0;
}
static void __exit param_demo_exit(void)
{
pr_info("param_demo: module unloaded\n");
pr_info("param_demo: final count = %d\n", count);
pr_info("param_demo: final name = %s\n", name);
}
module_init(param_demo_init);
module_exit(param_demo_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kernel Dev");
MODULE_DESCRIPTION("Module parameter passing demo");
Makefile
obj-m := param_demo.o
KDIR := /path/to/android/kernel/source
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
编译与加载
- 将
param_demo.c和Makefile放入同一目录,KDIR指向Android内核源码树(需已编译过并生成modules目标)。 - 执行
make生成param_demo.ko。 - 将
param_demo.ko推送到设备:adb push param_demo.ko /data/local/tmp/ - 加载模块并传参:
adb shell
su
cd /data/local/tmp
# 方式1:insmod传参
insmod param_demo.ko count=5 name="test_dev" arr=1,2,3,4
# 方式2:modprobe传参(需将ko放入/lib/modules/对应目录并运行depmod)
modprobe param_demo count=3 name="mdev" arr=7,8
验证方法
- 加载后执行
dmesg | tail -20,应看到打印的count、name、arr_argc及数组各元素值,与传入参数一致。 - 执行
ls /sys/module/param_demo/parameters/,应看到count、name、arr三个参数节点。 - 运行时修改参数:
echo 10 > /sys/module/param_demo/parameters/count,然后卸载模块,dmesg中final count应显示为10,证明参数可读写。 - 卸载模块:
rmmod param_demo,dmesg应显示卸载日志及最终参数值。
预期输出(dmesg片段)
param_demo: module loaded
param_demo: count = 5
param_demo: name = test_dev
param_demo: arr_argc = 4
param_demo: arr[0] = 1
param_demo: arr[1] = 2
param_demo: arr[2] = 3
param_demo: arr[3] = 4
关键说明
module_param_array的第三个参数&arr_argc是输出参数,内核自动填充实际传入的元素个数,无需手动赋值。- 权限位
0644使参数在sysfs中可读可写(root可写),便于运行时调整。 - 若使用
modprobe,需确保param_demo.ko已安装到内核模块目录并执行depmod更新依赖。 - 数组参数最大长度由数组定义决定(此处为4),超出部分会被内核丢弃并告警。