本文主要是介绍驱动基础——带参数的内核模块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
- 0. 引言
- 1. 带参数的内核模块
- 1.1 传入参数
- 1.2 内核模块代码
- 1.3 修改Makefile
- 1.4 模块编译
- 1.5 加载/卸载模块
- 2. 小结
- 参考
本文使用环境:
内核版本:Linux 3.0.15 / iTop4412_Kernel_3.0
硬件平台:armv7 / itop-4412
编译环境:Ubuntu Linux 12.04 LTS / gcc version 4.4.1 (Sourcery G++ Lite 2009q3-67)
0. 引言
在上一篇文章中简要说明了linux
内核模块的使用,simple_module.c
中仅分别在模块加载函数和模块卸载函数中添加了调用打印,linux
内核还提供了给内核模块传入参数的机制,该机制和使用c
语言在main
函数中通过命令行传入参数一样简单。
1. 带参数的内核模块
1.1 传入参数
linux
内核中,可以借助module_param
和module_param_array
函数完成参数传递,前者支持单个
参数传递,后者支持多个
参数传递。形式如下:
module_param(name, type, perm)
module_param_array(name, type, nump, perm)
各参数意义如下表:
参数 | 参数意义 |
---|---|
name | 模块参数名 |
type | 模块参数数据类型,可以为:byte 、short 、ushort 、int 、uint 、long 、ulong 、charp 、bool 等 |
nump | 参数数量(数组元素个数,类型为指针) |
perm | 模块参数访问权限,具体定义可以查看include/linux/stat.h 文件常见权限参数: S_IRUSR 00400 文件所有者可读S_IWUSR 00200 文件所有者可写S_IXUSR 00100 文件所有者可执行 |
1.2 内核模块代码
使用module_param
和module_param_array
函数可以传递定义在模块文件中的参数,也可以在加载时通过命令行传入,以下模块para_simple_module.c
包含了这两种方式:
#include <linux/init.h>
#include <linux/module.h>static const char* module_name = "para_simple_module";
module_param(module_name, charp, S_IRUSR);static int input_number;
module_param(input_number, int, S_IRUSR);static int input_array[10];
module_param_array(input_array, int, &input_number, S_IRUSR);static int __init para_module_init(void)
{int i;printk(KERN_INFO "%s called\n", __FUNCTION__);printk(KERN_INFO "\ninput param: \n");printk(KERN_INFO "module_name = %s\n", module_name);printk(KERN_INFO "input_number = %d\n", input_number);for(i = 0; i < input_number; i++){printk(KERN_INFO "input_array[%2d] = %d\n", i, input_array[i]);}return 0;
}static int __exit para_module_exit(void)
{printk(KERN_INFO "%s called\n", __FUNCTION__);return 0;
}module_init(para_module_init);
module_exit(para_module_exit);MODULE_AUTHOR("ryan");
MODULE_LICENSE("GPL v2");
该模块定义了3个参数:module_name
、input_number
和input_array[10]
。module_name
为模块内置的静态参数;input_number
和input_array[10]
为模块加载时输入的动态参数,input_number
会随输入的input_array
元素个数变化,因此第11行中module_param_array
函数需要传入input_number
的指针&input_number
。
1.3 修改Makefile
修改当前para_simple_module.c
源码路径下Makefile
文件,该Makefile
将调用内核目录中的Makefile
完成para_simple_module
模块编译
#!/bin/bash
#将simple_module.c这个文件编译成中间文件simple_module.o
obj-m += para_simple_module.o #linux内核源码路径
KDIR := /home/topeet/android4.0/iTop4412_Kernel_3.0#当前目录变量
PWD ?= $(shell pwd)#make命名默认寻找第一个目标
#make -C就是指调用执行的路径
#$(KDIR)Linux源码目录,当前环境指的是/home/topeet/android4.0/iTop4412_Kernel_3.0
#$(PWD)当前目录变量
#modules要执行的操作
all:make -C $(KDIR) M=$(PWD) modules
#make clean执行的操作是删除后缀为o的文件
clean:rm -rf *.o *.ko *.mod.c *.order *.symvers
1.4 模块编译
Makefile
修改完成后,在para_simple_module.c
源码路径下执行make
命令编译模块,编译完成后将在para_simple_module.c
源码路径下产生para_simple_module.ko
文件,该文件即待加载的模块
文件。最后,将模块
文件拷贝到NFS
根文件系统目录下备用。
1.5 加载/卸载模块
启动开发板,进入/system/drvbin/
路径执行insmod para_simple_module.ko input_array=1,2,3,4,5,6,7,8,9,10
命令安装模块,然后执行rmmod para_simple_module
命令卸载模块。
模块加载时首先打印了模块内置的module_name
参数,随后分别打印了input_number
参数和input_array
数组参数。
当输入的参数个数超过了input_array
数组成员数时,加载执行将失败;当输入参数存在空格时,加载执行也会失败。
2. 小结
本文首先介绍了linux
内核模块传入参数的方式:module_param
和module_param_array
宏,并基于这两个宏实现了带参数的内核模块,最后通过实际运行验证带参数内核模块的可行性。
参考
- 《Linux设备驱动开发详解-基于最新的Linux4.0内核》第4章
- 《itop-4412开发板之精英版使用手册_v4.0》第11章
这篇关于驱动基础——带参数的内核模块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!