LDD学习笔记系列之一
2018-11-30 本文已影响0人
卐卍扫地僧卐卍
预备知识
头文件
#include <linux/module.h> //可装载模块需要的大量符号和函数定义
#include <linux/init.h> //指定初始化和清楚函数
#include <linux/moduleparam.h> //装载模块时向模块传递参数
#include <linux/kernel.h> /* printk() */
#include <linux/errno.h> /* error codes */
描述性定义
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR(author);
MODULE_DESCRIPTION(description);
MODULE_VERSION(version_string);
MODULE_DEVICE_TABLE(table_info);
MODULE_ALIAS(alternate_name);
重要宏
module_init(init_function);
module_exit(cleanup_function);
module_param(name, type, perm);/* 变量名;type:bool\invbool\charp\int\long\short\uint\ulong\ushort;S_IRUGO:sysfs入口项的访问许可掩码 */
module_param_array(name, type, num, perm);
EXPORT_SYMBOL(symbol);
EXPORT_SYMBOL_GPL(symbol); /* 导出的符合限于GPL许可证下的模块使用 */
模块装载和移除
insmod
modprobe
rmmod
lsmod |grep
初始化和关闭
static int __init initialization_function(void)
{
/* 初始化代码 */
}
module_init(initialization_function);
static void __exit cleanup_function(void)
{
/* 清除代码 */
}
module_exit(cleanup_function);
- __init标记表明该函数仅在初始化期间使用
- __exit标记表面该函数仅在模块被卸载或系统关闭时被调用
- 追求效率的代码中使用goto语句是最好的错误恢复机制
examp
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
char *print_str = "<1>EXAMPLE: init\n";
int rept_cn = 2;
module_param(rept_cn, int, S_IRUGO);
module_param(print_str, charp, S_IRUGO);
MODULE_LICENSE("Dual BSD/GPL");
static int example_init(void) {
int index =0;
for(index = 0; index<rept_cn; index++){
printk(print_str);
}
return 0;
}
static void example_exit(void) {
printk("<1>EXAMPLE: exit\n");
}
module_init(example_init);
module_exit(example_exit);
obj-m := example.o
ifeq ($(KERNELDIR),)
KERNELDIR=/lib/modules/$(shell uname -r)/build
endif
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean