从 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 the * preferred over using init_module() and cleanup_module(). * * Copyright (C) 2001 by Peter Jay Salzman * * 08/02/2006 - Updated by Rodrigo Rubira Branco <rodrigo@kernelhacking.com> */ /* Kernel Programming */ #define MODULE #define LINUX #define __KERNEL__ #include <linux/module.h> // Needed by all modules #include <linux/kernel.h> // Needed for KERN_ALERT #include <linux/init.h> // Needed for the macros static int hello_2_init(void) { printk(KERN_ALERT "Hello, world 2\n"); return 0; } static void hello_2_exit(void) { printk(KERN_ALERT "Goodbye, world 2\n"); } module_init(hello_2_init); module_exit(hello_2_exit); MODULE_LICENSE("GPL"); |
现在我们已经掌握了两个真正的内核模块。以我们如此高的生产力,我们应该有一个强大的 Makefile。这是一个更高级的 Makefile,它将同时编译我们的两个模块。它针对简洁性和可扩展性进行了优化。如果您不理解它,我强烈建议您阅读 makefile info 页面或 GNU Make 手册。
示例 2-4。用于我们两个模块的 Makefile
WARN := -W -Wall -Wstrict-prototypes -Wmissing-prototypes INCLUDE := -isystem /lib/modules/`uname -r`/build/include CFLAGS := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE} CC := gcc-3.0 OBJS := ${patsubst %.c, %.o, ${wildcard *.c}} all: ${OBJS} .PHONY: clean clean: rm -rf *.o |
作为给读者的练习,如果我们在同一个目录中有另一个模块,例如hello-3.c,您将如何修改此 Makefile 以自动编译该模块?