2.5. 你好世界(第 4 部分):许可和模块文档

如果您运行的是 2.4 或更高版本的内核,您可能在加载专有模块时注意到类似这样的信息

# insmod xxxxxx.o
Warning: loading xxxxxx.ko will taint the kernel: no license
  See http://www.tux.org/lkml/#export-tainted for information about tainted modules
Module xxxxxx loaded, with warnings
	

在内核 2.4 及更高版本中,设计了一种机制来识别在 GPL(及其友元)下许可的代码,以便可以警告人们该代码不是开源的。这是通过MODULE_LICENSE()宏完成的,这在下一段代码中演示。通过将许可证设置为 GPL,您可以阻止打印警告。此许可证机制在linux/module.h:

/*
 * 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
 */

中定义和记录。类似地,MODULE_DESCRIPTION()用于描述模块的功能,MODULE_AUTHOR()声明模块的作者,以及MODULE_SUPPORTED_DEVICE()

声明模块支持的设备类型。linux/module.h中,并且内核本身不使用它们。它们仅用于文档,可以通过像 objdump 这样的工具查看。作为给读者的练习,尝试搜索linux/drivers以查看模块作者如何使用这些宏来记录他们的模块。

/usr/src/linux-2.6.x/中使用类似 grep -inr MODULE_AUTHOR * 的命令。不熟悉命令行工具的人可能会喜欢一些基于 Web 的解决方案,搜索提供使用 LXR 索引的内核树的站点。(或者在您的本地机器上设置它)。传统 Unix 编辑器的用户,例如 emacs vi ,也会发现标签文件很有用。它们可以通过在

中执行 make tags make TAGS 生成。中使用类似 grep -inr MODULE_AUTHOR * 的命令。不熟悉命令行工具的人可能会喜欢一些基于 Web 的解决方案,搜索提供使用 LXR 索引的内核树的站点。(或者在您的本地机器上设置它)。一旦您在内核树中有了这样的标签文件,您可以将光标放在某个函数调用上,并使用一些组合键直接跳转到定义函数。

示例 2-6. hello-4.c

/*  
 *  hello-4.c - Demonstrates module documentation.
 */
#include <linux/module.h>	/* Needed by all modules */
#include <linux/kernel.h>	/* Needed for KERN_INFO */
#include <linux/init.h>		/* Needed for the macros */
#define DRIVER_AUTHOR "Peter Jay Salzman <p@dirac.org>"
#define DRIVER_DESC   "A sample driver"

static int __init init_hello_4(void)
{
	printk(KERN_INFO "Hello, world 4\n");
	return 0;
}

static void __exit cleanup_hello_4(void)
{
	printk(KERN_INFO "Goodbye, world 4\n");
}

module_init(init_hello_4);
module_exit(cleanup_hello_4);

/*  
 *  You can use strings, like this:
 */

/* 
 * Get rid of taint message by declaring code as GPL. 
 */
MODULE_LICENSE("GPL");

/*
 * Or with defines, like this:
 */
MODULE_AUTHOR(DRIVER_AUTHOR);	/* Who wrote this module? */
MODULE_DESCRIPTION(DRIVER_DESC);	/* What does this module do */

/*  
 *  This module uses /dev/testdevice.  The MODULE_SUPPORTED_DEVICE macro might
 *  be used in the future to help automatic configuration of modules, but is 
 *  currently unused other than for documentation purposes.
 */
MODULE_SUPPORTED_DEVICE("testdevice");