Linux 内核模块开发基本知识

来源:互联网 发布:凸包算法 matlab 编辑:程序博客网 时间:2024/06/01 23:57

Linux 内核模块开发

1、 什么是内核模块?

避免内核镜像太大,占用太多的内存资源,所以可以编译进内核模块中去。

特点:动态的加载与卸载;不会被编译进内核镜像文件。

2、 学习方法。

范例程序->思维导图(指导性,纲领性,很重要)->自己动手编写程序。

3、 范例分析

#include <linux/init.h>//必须包含的两个头文件

#include <linux/module.h>

 int static hello_init(void)//注意加载函数返回值是int型

{

printk(KERN_WARNING"Hello, world !\n");

return 0;

}

void static hello_exit(void)//卸载函数返回值是void型

{

printk (KERN_INFO "Goodbye, world\n");

}

module_init(hello_init);//是一个宏,在这里调用加载函数

module_exit(hello_exit);//是一个宏,在这里调用卸载函数

4、与应用程序的区别

A、没有main函数,但是内核模块有入口函数和出口函数,或者叫加载函数卸载函数

内核模块安装的时候调用加载函数,卸载的时候调用卸载函数。

B、应用程序从头到尾执行程序,执行完从内存中消失,内核模块初始化结束时模块仍然存在于内存中,直到卸载函数被调用,模块才从内存中消失。

5、 内核模块的Makefile

内核模块的Makefile的首字母M必须大写,

一个obj-m后面加几个*.o文件,就生成几个内核模块,不能连续写几个obj-m,因为后面生成的内核模块会把前面的生成的内核模块覆盖掉。

当一个*.c文件调用其他文件*.c的函数时,得声明。

注意有多个*.c文件时的makefile的编写,

6、安装于卸载

当有用户使用该模块时,不能卸载该模块,用lsmod查看当前模块。

卸载模块命令rmmod 模块名字,

安装模块命令insmod模块名字.ko

6、 可选项

模块申明,让程序更加符合一些规范协议,eg:GPL,更加符合可读性,

                    申明模块遵守的协议MODILE_LICENSE(“遵守的协议”)

                    申明模块作者MODULE_AUTHOR(“作者”)

                    申明模块功能MODULE_DESCRIPTION(“功能”)

申明模块版本MODULE_VERSION(“版本”)

模块参数,在应用程序中int main(intargc, char** argv)argc表示命令行输入的参数个数,argv中保存输入的参数。通过宏module_param指定保存模块参数的变量。模块参数用于在加载模块时传递参数给模块。

module_param(name,type,perm)

name:变量的名称

type:变量类型,bool:布尔型 int:整型 charp:字符串型

perm是访问权限。S_IRUGO:读权限 S_IWUSR:写权限

例:

int a = 3;

char *st;//不需要去分配空间,系统会自动分配空间

module_param(a,int,S_IRUGO);

module_param(st,charp,S_IRUGO);//charp表示字符串

 在insmod的时候后面可以带参数,例如:insmod test.ko a=1 str=sfdsf.

符号打出:函数,变量就是符号,模块的里面的符号要被别的模块使用,就得必须通过申明来输出这些符号到Linux系统中去被其他的模块调用,

                       申明函数EXPORT_SYMBOL(符号名),该函数写在定义函数或变量的文件里面。

   EXPORT_SYMBOL_GPL(符号名) 该函数只能用于包含GPL许可证的模块。

7、 内核打印

Printk函数,通过优先级来对消息进行分类。控制是否打印到屏幕。

在<linux/kernel.h>中定义了8种记录级别。按照优先级递减的顺序分别是:

KERN_EMERG  “<0>”用于紧急消息,常常是那些崩溃前的消息。

KERN_ALERT    “<1>”需要立刻行动的消息。

KERN_CRIT     “<2>”严重情况。

KERN_ERR     “<3>”错误情况。

KERN_WARNING“<4>”有问题的警告

KERN_NOTICE   “<5>”正常情况,但是仍然值得注意

KERN_INFO    “<6>”信息型消息

KERN_DEBUG   “<7>”用作调试消息

没有指定优先级的printk默认使用DEFAULT_MESSAGE_LOGLEVEL优先级,它是一个在kernel/printk.c中定义的整数。

#define DEFAULT_MESSAGE_LOGLEVEL  4     /*KERN_WARNING */

0 0