驱动文件:hello.c
#include<linux/init.h> //此头文件指定初始化和清楚函数 module_init();module_exit();
#include <linux/module.h> //此头文件包含有可装载模块需要的大量符号和函数的定义
static int _init hello_init(void)
{
printk(KERN_WARNING "hello world.\n");
return 0;
}
static void _exit hello_exit(void)
{
printk(KERN_WARNING "goodbye world.\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL');
MODULE_DESCRIPTION("just a simple module for hello world");
运行环境:2440开发板,内核版本2.6.30.4
开发环境:window下source insight以及PC机上的VMware虚拟机上的Ubuntu系统
在虚拟机ubuntu上配时实现好的一个NFS网络文件系统
除了上面的hello.c文件,我们还需要一个makefile文件;
ifneq($(KERNELRELRASE),)
obj-m:=hello.o
else
//KERNELDIR:=/lib/modules/$(shell uname -r)/build
KERNELDIR:=/usr/src/linux-2.6.30.4
all:
make -C $(KERNELDIR) M=$(PWD) modules ARCH =arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.o *.ko *.mod.o *mod.c *.symvers
endif
-------------------------------------------------
虚拟机上的操作:
1,建立一个单独的文件夹用于存放hello模块以及makefile文件
2,编译模块,然后拷贝模块到制作好的NFS文件系统
开发板上的操作;
insmod hello.ko
lsmode
rmmod hello
-----------------------------------
分析上面的makefile
KERNELRELEASE 是内核源代码顶层所定义的一个变量,当makefile第一次执行时,这个变量并没有定义,因此直接执行else中的内容,uname -r
命令输出当前系统所使用的内核版本号,/lib/modules/$(shell uname -r)/bulid 这个就是linux内核源码所在的文件目录,当执行到modules时,-C $(KERNELDIR)
指明跳转到内核源码目录读取那里的makefile; M=$(PWD)表明然后返回到当前目录继续读入,执行当前的makefile
当从内核源码目录返回时,KERENALRELEASE已经被定义,kbuild也被启动区解析kbuild语法语句,make将执行else之前的内容。else 之前的内容为kbi
kbuild的语法语句,指明模块的源码中个文件的依赖关系,以及要生成的目标模块名。
obj-m后面跟着的就是最终的模块名。
hello_driver.o make会再该目录下自动找到hello——driver.c进行编译
最后通过insmod加载驱动模块,用rmmod卸载模块,此外还有两个关于模块的命令:lsmod modprob modinfo,lsmod用来列出所有的模块,modprobe命令,可以智能插入模块,它可以根据模块间依存关系,以及/etc/modules.conf文件中的内容智能插入模块。
上面加载模块的例子在加载和卸载的过程中,就会有信息输出,通过dmesg打印输出。