002-第一个内核模块的代码

什么是内核模块

内核模块可以简单理解为运行在内核空间的程序。与用户空间的应用程序一样其也有固定的模式。

第一个内核模块

先来看一个标准的应用程序

  • HelloWorld.c
#include "stdio.h"
int main(int argc, char** argv)
{
	printf("Hello World!");
}

以上代码大家一定不会陌生。还记得第一次学习这个程序时的心情么,大多数人可能都不理解它为什么要这么写,只是记住了它的格式而已。那么对于内核模块也是一样的,最开始我们不需要理解那么多,只需要记住内核模块的格式即可。

第一个内核模块

  • HelloKernelModule.c
#include "linux/init.h"
#include "linux/module.h"

static int __init hello_module_init(void)
{
	printk("Initialize module\n");
	return 0;
}

static void __exit hello_module_exit(void)
{
	printk("Exit module\n"); 
}

module_init(hello_module_init);
module_exit(hello_module_exit);

MODULE_LICENSE("GPL");

module_init() 和 module_exit()

module_init()用于声明模块的入口函数。用户应用程序的入口函数名固定为main这是c语言标准规定的。而内核模块的入口函数名可以根据需要随便起名。只需要用module_init()声明一下即可。
module_exit()用于声明内核模块退出(卸载)时需要执行的函数。

如果你了解C++,那么可以把module_init()module_exit()声明的函数看作是C++类的构造函数和析构函数。当模块被加载时会执行module_init()声明的函数(代码中的hello_module_init()),当模块被卸载时会执行module_exit()声明的函数(代码中的hello_module_exit())。

printk

C语言的标准函数是建立在操作系统外层API之上的,而内核模块属于操作系统的内层因此不能直接调用C语言标准函数,如printf()便无法使用 。在内核打印信息需要使用printk()。该函数的用法可以在网上找到很多说明,这里就不赘述了。

MODULE_LICENSE

MODULE_LICENSE用于声明当前模块执行的开源协议标准。由于kernel是开源项目,如果你编写的内核模块不兼容GPL协议,内核会认为你编写的模块‘污染’了内核。 因此一般情况都需要用MODULE_LICENSE对模块的协议进行声明。

在内核代码include/linux/module.h中可以看到MODULE_LICENSE,及其可以使用的协议。

/*
 * The following license idents are currently accepted as indicating free
 * software modules
 *
 *	"GPL"				[GNU Public License v2 or later]
 *	"GPL v2"			[GNU Public License v2]
 *	"GPL and additional rights"	[GNU Public License v2 rights and more]
 *	"Dual BSD/GPL"			[GNU Public License v2
 *					 or BSD license choice]
 *	"Dual MIT/GPL"			[GNU Public License v2
 *					 or MIT license choice]
 *	"Dual MPL/GPL"			[GNU Public License v2
 *					 or Mozilla license choice]
 *
 * The following other idents are available
 *
 *	"Proprietary"			[Non free products]
 *
 * There are dual licensed components, but when running with Linux it is the
 * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
 * is a GPL combined work.
 *
 * This exists for several reasons
 * 1.	So modinfo can show license info for users wanting to vet their setup
 *	is free
 * 2.	So the community can ignore bug reports including proprietary modules
 * 3.	So vendors can do likewise based on their own policies
 */
#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)

你可能感兴趣的:(kernel,module)