2.3. 你好世界(第二部分)

从 Linux 2.4 开始,您可以重命名模块的 init 和 cleanup 函数;它们不再必须被调用init_module()cleanup_module()分别。这是通过module_init()module_exit()宏来实现的。这些宏定义在linux/init.h。唯一的注意事项是,您的 init 和 cleanup 函数必须在调用宏之前定义,否则您会收到编译错误。这是一个使用此技术的示例

示例 2-3. hello-2.c

/*  
 *  hello-2.c - Demonstrating the module_init() and module_exit() macros.
 *  This is preferred over using init_module() and cleanup_module().
 */
#include <linux/module.h>	/* Needed by all modules */
#include <linux/kernel.h>	/* Needed for KERN_INFO */
#include <linux/init.h>		/* Needed for the macros */

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

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

module_init(hello_2_init);
module_exit(hello_2_exit);

现在我们已经掌握了两个真正的内核模块。添加另一个模块就这么简单

示例 2-4. 适用于我们两个模块的 Makefile

obj-m += hello-1.o
obj-m += hello-2.o

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

现在看看linux/drivers/char/Makefile以获得一个真实的示例。正如您所见,有些东西被硬编码到内核中 (obj-y),但是那些 obj-m 都去哪儿了呢? 熟悉 shell 脚本的人可以很容易地发现它们。 对于那些不熟悉的人,您在各处看到的 obj-$(CONFIG_FOO) 条目会扩展为 obj-y 或 obj-m,具体取决于 CONFIG_FOO 变量是否已设置为 y 或 m。 顺便说一句,这些正是您在linux/.config文件中设置的变量类型,上次您说 make menuconfig 或类似命令时。