实在是让大家久等了,因为最近离职,所以繁锁的事情很多,今天终于把离职手续给办完了,不过还有一堆事情没有做,如果更新的慢的话,请大家多多包涵。言归正传。
俗话说的好:光说不练假把式。很明显本帅哥不是假把式。为了让大家一起对驱动模型有直观的认识,小弟花了一点点时间写了几个小例子(目前只有一个)。就是为了让大家领会最神秘的驱动模型,有了这些小例子,结合我前面两篇源码分析的文章,哥可以告诉你,你已经具备内核分析的基本能力了。
首先说一下我的环境:我linux是装在虚拟机上的,装的linux发行版是CentOS5.4。后面将内核升级到了2.6.32.3。为什么要选这个版本呢?因为网上有对应的内核升级教程,这可以省掉我很多在我看来不是很重要的文字(哥很懒滴)。可能有的朋友会说直接装一个发行版的linux不就得了,为什么要升级自已的内核呢?这个我觉得有必要说明一下。你如果直接从网上下个发行版装上以后,只有一堆内核头文件(我喜欢用的centos5和rhel5是这样的),如果你要在不是自已写的内核源码中加入调试信息就非常不方便了,如果你自已下载源码编译内核,你就可以直接在内核源码中加调试信息,再编译就OK了。再说了,如果没玩过的同志花个一天时间把这个东西给搞好了,也会增加自已的信心。OK。游戏开始了:
先给出源码:
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/init.h>
#define wwhs_dbg(dbgbuf) printk(KERN_ERR"wwhs:%s\n",dbgbuf);
static struct kobject *wwhs_kobj;
static int __init wwhs_drvmode_init()
{
wwhs_dbg("drvmode_init");
wwhs_kobj = kobject_create_and_add("wwhs_drvmode",NULL);
if (!wwhs_kobj)
wwhs_dbg("out of memory");
return 0;
}
static void __exit wwhs_drvmode_exit()
{
wwhs_dbg("drvmode_exit");
kobject_del(wwhs_kobj);
}
module_init(wwhs_drvmode_init);
module_exit(wwhs_drvmode_exit);
MODULE_AUTHOR("wwhs");
MODULE_DESCRIPTION("wwhs_drvmode");
MODULE_LICENSE("GPL");
下面给出makefile,makefile请根据自已的开发环境进行适当调整。
obj-m+=wwhs_drvmode.o
KERNELDIR=/opt/linux-2.6.32.3
PWD:=$(shell pwd)
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o* *.ko* *.mod.c *.cmd *.symvers .tmp_versions .*.cmd
将这两个文件放在同一目录下,然后进入root 模式。
make一下。
如果不出意外的话应该可以生成wwhs_drvmode.ko这样一个内核模块。
执行:insmod wwhs_drvmode.ko
执行:dmesg
应该可以看到打印信息了吧。
好,我们进去/sys目录下看看。
见证奇迹的时候到了,我们可以激动的看到在/sys目录下面多了一个名为wwhs_drvmode的目录。
执行:rmmod wwhs_drvmode
执行:dmesg
可以看到有exit的打印。
再进/sys目录下,wwhs_drvmode这个目录不见了。
神奇啊!
这与我们之前的源码分析是一一对应的,真是太神奇了。
如果对之前的源码分析没兴趣的同志现在应该有兴趣了吧,如果没看懂马上回过头去看第一二小节,再仔细看一遍。后面游戏会越来越好玩。先抽根烟。下回见。