书写首个内核模块

在《为Ubuntu换颗“心”》一文中,我们已经了解到了如何去编译安装新的Kernel,编译过程也生成了相应的内核树,为什么要生成内核树呢?其实就跟我们写应用程序时一样,写程序会调用到其他的库文件或其他文件生成的目标文件,最后再由链接器把这些目标文件处理生成可执行文件,就是这道理,这为我们后期调试内核模块时打下了应有的基础,有了这编译调试内核模块的基础,那么开发环境呢?当然可以参考下《VI改造计划》,全命令行的开发模式最适合我们了,我们做底层就要有做底层的风格啊。好,既然这两个基础条件都有了,接下来就可以开始尝试写我们的首个模块了。 于是接下来我们按照学习编程语言时写一个我们自己的Hello world——Hello xinu,向自己问声好,表扬下自己迈出这一步,踏入了内核驱动模块的圈。

下面是我们的hello_xinu.c文件内容:

#include
#include
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

你可能感兴趣的:(书写首个内核模块)