这部分内容主要记录驱动一些琐碎知识。
1 许可证条款
GPL(General Public License),Linux是遵循GPL发布的。如果想了解GPL详情,可阅读内核源码顶层目录的COPYING文件。
2 内核符号表
顾名思义即内核提供的一个符号列表,驱动模块在遵循相关许可证条件下可引用这些符号;该符号可能是其他驱动模块提供的全局变量或函数,一般后者居多。
模块可通过"EXPORT_SYMBOL(name)"或"EXPORT_SYMBOL_GPL(name)"导出给定的符号;其它模块通过extern声明后,则可引用;其中_GPL导出的符号,只能被GPL许可证下的模块使用。
示例
-
/**
-
* file1.c
-
*/
-
#include <linux/init.h>
-
#include <linux/module.h>
-
static void display(void)
-
{
-
printk(KERN_INFO"Hello Kozo\n");
-
}
-
EXPORT_SYMBOL_GPL(display); /* display函数以GPL协议导出 */
-
static __init int file1_init(void)
-
{
-
printk(KERN_INFO("file1 init\n");
-
return 0;
-
}
-
static __exit void file1_exit(void)
-
{}
-
module_init(file1_init);
-
module_exit(file1_exit);
-
/**
-
* file2.c
-
*/
-
#include <linux/init.h>
-
#include <linux/module.h>
-
MODULE_LICENSE("GPL"); /*如果不设置GPL许可证,则无法使用diaplay符号*/
-
extern void display(void);
-
static __init int file2_init(void)
-
{
-
printk("file2 init\n");
-
display();
-
return 0;
-
}
-
static __exit void file2_exit(void)
-
{}
如果使用"insmod"加载时,要先加载file1模块,再加载file2模块,卸载则反过来;如果使用"modprobe",则直接加载file2模块即可,前提是file1模块在file2模块的路径下。
3 模块参数
模块参数类似于函数参数,在驱动模块中通过宏"module_param"或"module_param_array"声明,通常这些模块参数有个初始值,但可在加载此模块时重新赋值。
内核接口:
-
module_param(name, type, perm); /*声明单个参数*/
-
module_param_array(name, type, num, perm); /*声明数组参数*/
宏参数说明
name: 模块参数名称,即全局变量的名称;
type: 模块参数类型;内核支持的类型如下
类型
|
说明
|
bool
|
布尔值,关联的变量应该是int变量
|
invbool
|
返回布尔值
|
charp
|
字符指针值
|
int
|
具有不同长度的基本整数值;以u开头的用于无符号值
|
long
|
short
|
uint
|
ulong
|
ushort
|
num: 声明数组时,指定数组个数;如果为NULL,则表明不关心数组个数。
perm: 访问许可值。相关数值可参照"
"中的定义;一般用得较多的是S_IRUGO,S_IWUSR。
使用示例
-
static char *p = "test";
-
static int n = 0;
-
static int array[10] = {0};
-
static int num = 10;
-
module_param(p, charp, S_IRUGO);
-
module_param(n, int, S_IRUGO);
-
module_param_array(array, int, &num, S_IRUGO);
加载模块时,可对这些模块参数赋值,假如该模块名为"kozo.ko",则可使用
-
#insmod kozo.ko p="kozo" num=10 array=1,2,3,4,5,6,7,8,9,10
4 其他宏使用说明
-
MODULE_LICENSE("许可证");
-
MODULE_AUTHOR("模块作者");
-
MODULE_DESCRIPTION("模块用途描述");
-
MODULE_VERSION("代码修订号");
-
MODULE_ALIAS("模块的别名");
-
MODULE_DEVICE_TABLE("模块支持的设备");
上述宏名称已足够表明了它们的意图了。
注:文章会在未来某个时刻被更新。
转载本文请注明出自:add358.blog.chinaunix.net
阅读(1361) | 评论(0) | 转发(0) |