#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int hello_init(void)
{
printk(KERN_ALERT"Hello world\n");return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT"Good bye world\n");}
module_init(hello_init);
module_exit(hello_exit);
MODULE_DESCRIPTION ("A simple Hello World Module");
MODULE_ALIAS("a simple module");
对于这点代码,相信大家都能看明白,不明白的可以查看一下linux设备驱动一书,我在这里向大家介绍的主要问题不在于这几行代码,而在于怎么样正确的编译这一段代码,相信这也是大家遇到问题最多的地方。
2 Makefile编写多种多样,下面这个Makefile我是验证过的:
版本1:
# Makefile for hello module
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
endif
clean:
$(shell rm -f *.bak)
$(shell rm -f hello.o)
$(shell rm -f hello.ko)
$(shell rm -f hello.mod.c)
$(shell rm -f hello.mod.o)
版本2:
obj-m := modules.o #要生成的模块名
modules-objs:= mymod.o #生成这个模块名所需要的目标文件
KDIR := /lib/modules/`uname -r`/build
PWD := $(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o .* .cmd *.ko *.mod.c .tmp_versions
现在我来说明一下这个Makefile。请记住是大写的Makefile而不是小写的makefile;
obj-m :这个变量是指定你要声称哪些模块模块的格式为 obj-m := <模块名>.o
modules-objs :这个变量是说明声称模块modules需要的目标文件 格式要求 <模块名>-objs := <目标文件>
切记:模块的名字不能取与目标文件相同的名字。如在这里模块名不能取成 mymod;
KDIR :这是我们正在运行的操作系统内核编译目录。也就是编译模块需要的环境
M= :指定我们源文件的位置
PWD :这是当前工作路径$(shell )是make的一个内置函数。用来执行shell命令。
我采用的是redhat AS4 版本,内核2.6.18-53
保存为Makefile
3 编译模块
命令行敲入 make -f Makfile
编译过程屏幕打印如下信息:
make -C /lib/modules/2.6.18-53.el5xen/build SUBDIRS=/home/writeDriver modules
make[1]: Entering directory `/usr/src/kernels/2.6.18-53.el5-xen-i686'
CC [M] /home/writeDriver/hello.o
Building modules, stage 2.
MODPOST
CC /home/writeDriver/hello.mod.o
LD [M] /home/writeDriver/hello.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.18-53.el5-xen-i686'
现在当前路径下出现hello.mod.c, hello.mod.o, hello.o, hello.ko几个文件,我们调用insmod hello.ko加载hello模块。
屏幕显示: hello world enter
OK,模块初始化的打印信息显示出来啦。
查看linux是否加载了hello模块,我们调用lsmod 来检视,shift +PageUp或者shift+PageDown来上下翻页,哇,看到我们先前加载的hello模块。
卸载模块可以在命令行键入:rmmod hello
屏幕打印出:
hello world exit
大功告成。
insmod: error inserting 'hello.ko': -1 Invalid module format 错误。这个错误是因为你编译模块的时候采用的源码的版本同你系统现在使用的内核的版本不一致造成的,解决的方法就是使用和系统内核版本一致的内核源码树。