从 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 或类似命令时。