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驱动编写正式完成测试。
- Hello World驱动模块尝试<1>_在虚拟机Ubuntu上实现
- Hello World驱动模块尝试<2>_将驱动加载到mini210s开发板
- hello world!(驱动模块)
- Ubuntu下Hello World驱动实现全过程
- Ubuntu下Hello World驱动实现全过程
- Ubuntu下Hello World驱动实现全过程
- Ubuntu下Hello World驱动实现全过程
- Ubuntu下Hello World驱动实现全过程
- linux驱动学习1---Hello World模块
- 驱动开发-1 模块hello world
- 编写 Hello world 模块驱动
- 驱动学习,hello world模块
- 编写 Hello world 模块驱动
- TQ2440驱动-hello world 模块
- TQ2440驱动-hello world 模块
- TQ2440驱动-hello world 模块
- TQ2440驱动-hello world 模块
- FL2440驱动添加(1):hello world 驱动模块添加
- Apache Maven 入门篇 ( 上 )
- 静态代码块,非静态代码块,构造函数的分析
- 怎样提高语言组织能力
- 跨平台 PhoneGap 框架的调研 和 性能测试
- hdu4686 矩阵快速幂 多校第九场
- Hello World驱动模块尝试<1>_在虚拟机Ubuntu上实现
- 坚持学英语20130821-->my homework
- ORACLE正则表达式
- 关于数组(指针)作为参数
- 待执行
- 龙芯PMON编译
- android service生命周期分析与理解
- lucene series 2 document 文档 索引创建 基本索引操作
- SelectedIndexChanged事件