书写首个内核模块

在《为Ubuntu换颗“心”》一文中,我们已经了解到了如何去编译安装新的Kernel,编译过程也生成了相应的内核树,为什么要生成内核树呢?其实就跟我们写应用程序时一样,写程序会调用到其他的库文件或其他文件生成的目标文件,最后再由链接器把这些目标文件处理生成可执行文件,就是这道理,这为我们后期调试内核模块时打下了应有的基础,有了这编译调试内核模块的基础,接下来就可以开始尝试写我们的首个模块了。 
于是接下来我们按照学习编程语言时写一个我们自己的Hello world——Hello xinu,向自己问声好,表扬下自己迈出这一步,踏入了内核驱动模块的圈。
下面是我们的hello_xinu.c文件内容:
#include <linux/init.h>
#include <linux/module.h>

static int hello_xinu_init(void)
{
        printk("Hello xinu!\n");
        return 0;
}

static void hello_xinu_exit(void)
{
        printk("Bye xinu!\n");
}

module_init(hello_xinu_init);
module_exit(hello_xinu_exit);
源码写好后,在此只需确认整个模块的入口,即module_init对应的hello_xinu_init,而出口是hello_xinu_exit,这个在后面的操作中可以确认。
接下来需要编译时用到的Makefile文件,内容如下:
obj-m += hello_xinu.o

CUR_PATH:=$(shell pwd)
LINUX_KERNEL_PATH:=/home/xinu/linux-3.13.6

all:
        make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) modules

clean:
        make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) clean
此处只需要确认下LINUX_KERNEL_PATH这个变量的值,请根据实际来确认。
我这边最终的目录树如下:
 /home/xinu/xinu/linux_kernel_driver_l1/hello_xinu/
├── hello_xinu.c
└── Makefile 
好了,一切准备工作已就绪,接下来在命令行执行make,然后在hello_xinu目录下会生成hello_xinu.ko文件和其他中间文件,接下来在hello_xinu目录下执行sudo insmod hello_xinu.ko,然后执行demsg命令,就可以看到有如下内容输出: 
Hello xinu! 
此时执行lsmod可以看到如下内容输出: 
hello_xinu 12506 0 
我们再执行下sudo rmmod hello_xinu命令,然后再执行dmesg命令,有如下内容输出: 
Bye xinu! 
此时再执行lsmod,就看不到hello_xinu一项了,体验一番后,我们了解到insmod加载模块时对应执行的是module_init对应的函数,而rmmod卸载模块时对应执行的是module_exit对应的函数。 
就是这么容易,一个简单的试手模块就完成了,源码中printk对应C语言的printf,涉及到的命令有make、lsmod、insmod、rmmod、dmesg。当然我们可以在做完实验后执行make clean命令做下清尾操作。
参考网址:http://edsionte.com/techblog/archives/1336

评论

此博客中的热门博文

I/O映射之I/O端口

通过Netlink检测网线插拔

使用seq_file