Hello World驱动模块尝试<1>_在虚拟机Ubuntu上实现

来源:互联网 发布:淘宝寿衣 编辑:程序博客网 时间:2024/05/16 08:21

主要参考资料:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299871.html

平台:Ubuntu12.04,内核版本3.2.0-51-generic-pae(通过 uname -r 命令查看)

编写驱动程序时,首先必须建立内核源码树,刚开始的时候不知道构建内核源码树,导致make使用出现错误,如找不到头文件等问题。原因是先前的内核只需要有一套内核头文件就够了,但因为2.6的内核模块吆喝内核源码树中的目标文件连接,通过这种方式,可得到一个更加健壮的模块装载器,但也需要这些目标文件存在于内核目录树中。所谓内核树,我的理解和网上资料说的一致就是内核源码的一种逻辑形式。

网上的参考资料显示Ubuntu下是不自动安装内核源码的(后来在/usr/src中发现了linux-headers-3.2.0-51-generic-pae,并且在/lib/modules/build中找到了3.2.0-51-generic-pae,自己试着在该目录下按照相同步骤make了下,出现了错误,但是这个内核源码树直接可以使用,这个不懂为什么和网上说的不同),所以我就自己手动安装:

sudo apt-get install linux-source,通过该命令下载完成了3.2.0版本的内核,得到了linux-source-3.2.0.tar.bz2压缩包(在目录/usr/src下),然后就是解压tar xvf linux-source-3.2.0.tar.bz2.解压完成后就完全按照网上步骤构建内核源码树

1、make oldconfig不需要裁剪

2、make,这个过程花费时间较长

3、make bzImage,执行结束后可以在当前目录(/usr/src/linux-source-3.2.0)下看到一个新的文件:vmlinux,其属性是-rwxr-xr-x.

4、make modules

5、make modules_install

依次执行结束后,会在/lib/modules/下生成了新的目录3.2.48文件夹(这个不懂为什么生成的是这个版本的)。在随后的编译模块文件时,要用到该路径下的build目录,至此内核编译完成,可以reboot重启下系统,内核树建立完成。。。。。

简单的hello world驱动模块:

在/home/liuhui8989/Updown_minicom/Example/Driver目录下新建2个文件:hello.c和Makefile

hello.c文件:

#include<linux/init.h>
#include<linux/module.h>
MODULE_LICENSE("liuhui8989 BSD/GPL");
int init_moduless(void)
{
printk(KERN_ALERT"hello.world-this is the kernel speaking\n");
return 0;
}
void cleanup_moduless(void)
{
printk(KERN_ALERT"Short is the life of a kernel\n");
}


module_init(init_moduless);
module_exit(cleanup_moduless);

说明:

在调试过程中出现的问题:

开始时候函数命名分别为: void init_module()和void cleanup_module ( ),出现了以下错误打印信息:

root@ubuntu:/home/liuhui8989/Upload_minicom/Example/Driver#make

make -C/lib/modules/3.2.0-51-generic-pae/buildM=/home/liuhui8989/Upload_minicom/Example/Driver modules

make[1]: Entering directory`/usr/src/linux-headers-3.2.0-51-generic-pae'

  CC[M] /home/liuhui8989/Upload_minicom/Example/Driver/hello.o

/home/liuhui8989/Upload_minicom/Example/Driver/hello.c:15:1:error: redefinition of ‘init_module’

/home/liuhui8989/Upload_minicom/Example/Driver/hello.c:5:5:note: previous definition of ‘init_module’ was here

/home/liuhui8989/Upload_minicom/Example/Driver/hello.c:16:1:error: redefinition of ‘cleanup_module’

/home/liuhui8989/Upload_minicom/Example/Driver/hello.c:10:6:note: previous definition of ‘cleanup_module’ was here

make[2]: ***[/home/liuhui8989/Upload_minicom/Example/Driver/hello.o] Error 1

make[1]: ***[_module_/home/liuhui8989/Upload_minicom/Example/Driver] Error 2

make[1]: Leaving directory`/usr/src/linux-headers-3.2.0-51-generic-pae'

make: *** [modules] Error 2

总体来说就是module_init(init_moduless);
module_exit(cleanup_moduless);两句存在的问题,然后屏蔽这两条语句(暂时不是很清楚这两句是做啥的),出现了警告:

warning: function declaration isn’t a prototype,就是指函数声明不是函数原型(http://blog.csdn.net/fangyuanseu/article/details/6310367);

然后就声明中加了(void)警告就消除了,但是根据网上说的我屏蔽掉的两条语句是驱动模块中必须使用的,所以没办法只能通过修改函数名的方式实现了,也就有了最终的版本。

Makefile文件

obj-m:=hello.o
KERNELDIR:=/lib/modules/3.2.0-51-generic-pae/build
PWD:=$(shell pwd)
modules:(下一行属于是命令行,以Tab键开始)
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:(下一行属于是命令行,以Tab键开始)
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

请注意在该文件中我使用的目录是系统本身就有的/lib/modules/3.2.0-51-generic-pae/build,而没有使用我手动构建的源码树,主要是网上有说内核源码树的版本必须和自己Linux内核版本相同,故采用的是这个。后期测试了下/lib/modules/3.2.48/build同样是可以正确运行的

两个文件调试完成后,make后的正确打印信息

root@ubuntu:/home/liuhui8989/Upload_minicom/Example/Driver#make

make -C/lib/modules/3.2.0-51-generic-pae/buildM=/home/liuhui8989/Upload_minicom/Example/Driver modules

make[1]: Entering directory `/usr/src/linux-headers-3.2.0-51-generic-pae'

  CC[M] /home/liuhui8989/Upload_minicom/Example/Driver/hello.o

 Building modules, stage 2.

 MODPOST 1 modules

 CC     /home/liuhui8989/Upload_minicom/Example/Driver/hello.mod.o

  LD[M]  /home/liuhui8989/Upload_minicom/Example/Driver/hello.ko

make[1]: Leaving directory`/usr/src/linux-headers-3.2.0-51-generic-pae'

OK,这样就得到了我们的.ko文件。

继续执行,加载驱动

root@ubuntu:/home/liuhui8989/Upload_minicom/Example/Driver#sudo insmod ./hello.ko

root@ubuntu:/home/liuhui8989/Upload_minicom/Example/Driver#sudo lsmod

。。。。。。。

hello                  12394  0

。。。。。。。

看到这些我们就知道驱动加载成功了。

查看运行结果:

root@ubuntu:/home/liuhui8989/Upload_minicom/Example/Driver#cat  /var/log/syslog  |grep world

Aug 21 09:36:10 ubuntu kernel:[134874.880150] hello.world-this is the kernel speaking

成功执行了驱动。

驱动的卸载:

root@ubuntu:/home/liuhui8989/Upload_minicom/Example/Driver#rmmod hello

root@ubuntu:/home/liuhui8989/Upload_minicom/Example/Driver#cat  /var/log/syslog  |grep world

Aug 21 09:36:10 ubuntu kernel:[134874.880150] hello.world-this is the kernel speaking

root@ubuntu:/home/liuhui8989/Upload_minicom/Example/Driver#sudo lsmodModule    

查看结果自然是找不到hello这个驱动模块了。

到这hello world驱动编写正式完成测试。 



原创粉丝点击