上两篇文章记录了在ubuntu12.04上面初步实现一个驱动模块及其参数的问题:
下面记录一下,在ubuntu12.04上面实现字符驱动的过程,在看到LDD3(linux device driver 3rd)第三章的时候,讲解了字符设备驱动的实现,自然就找到了源码来进行查看和编译,但是,官方的源码包含了第三章到第六章的内容,对于新手来说,可能就会觉得很苦恼,因为后面的知识都还不会,而且代码混合在一起也不利于本章知识的掌握,下面就记录一下我源码分离的过程,以及在ubuntu12.04(kernel version 3.2.0-23-generic)上面编译,加载,测试,卸载的过程。
先给出最后可以运行的源码资源:http://download.csdn.net/detail/jiguangcanhen/8314973
-------------------------------------------------------------------------------------------
最后源码包含的文件有:
main.c Makefile scull.h scull.init scull_load scull_unload
分别说一下:
main.c:当然是模块的主体内容了。
Makefile:是编译脚本
scull.h:自定义的头文件,在main.c中进行了引用,声明了一些变量等。
scull.init:初始化脚本,在加载模块的时候创建设备节点,在卸载模块的时候删除设备节点等等。
scull_load:模块加载脚本。
scull_unload:模块卸载脚本。
--------------------------------------------------------------------------------------------
首先是main.c脚本的源码解析,这个大家参考这篇博客,讲解的很详细:http://blog.csdn.net/liuhaoyutz/article/details/7383313
--------------------------------------------------------------------------------------------
接着是Makefile脚本的解析,这个大家也参考这篇博客:http://blog.csdn.net/liuhaoyutz/article/details/7382956
这里,我只说一下需要修改的地方:
1.把scull-objs := main.o pipe.o access.o修改为scull-objs := main.o
原因也很简单,我们现在已经没有pipe.c和access.c了,这些是后面章节的内容,也是我们需要去除的部分。
2.这里在make的时候,还会出现一个错误的,这个留在后面给出。
--------------------------------------------------------------------------------------------
对于scull.init和scull_load和scull_unload就是三个shell脚本,对于这里,如果大家看不懂,请先阅读《shell入门与开发指南》
这里也是给出需要修改的地方:
1.FILES=" 0 0 1 1 2 2 3 3 priv 16
pipe0 32 pipe1 33 pipe2 34 pipe3 35
single 48 uid 64 wuid 80"
修改为:
FILES=" 0 0 1 1 2 2 3 3"
原因也很简单,就是后面的那些字符设备,我们都不需要了。
至于scull_load和scull_unload可以不用修改。
在具体的,大家就比对我的源码和官方源码的不同就可以了。
-------------------------------------------------------------------------------------------
下面就是make的过程:
问题1:Makefile.build:12: *** CFLAGS wa changed in ‘‘yourpath" . Fix it to use ccflags-y. Stop.
问题解决:也很简单,就是在Makefile中找到相应的问题,进行替换就可以了。
问题2:main.c:1:0: error: linux/config.h: No such file or directory.
问题解决:把#include <linux/config.h>这句话给注释掉就可以了。
问题3:error: implicit declaration of function ‘init_MUTEX’
问题解决:你可以报main.c在初始化使用到init_MUTEX的地方注释掉,也可以使用sema_init(sem,1);来进行替代。
--------------------------------------------------------------------------------------------
这样之后,make就通过了,ls看看现在的文件目录。
因为我们还没有加载模块,所以还无法看到我们创建的设备节点,加载模块的时候,需要root权限下才可以哦。
加载了模块之后,可以在/proc/modules中看到我们的模块。
可以在/dev下看到我们的设备。
可以看到我们设备的设备主编号为249,此编号分别为:0、1、2、3,名称分辨为scull0、scull1、scull2、scull3。并且c开头的话,说明我们的设备是字符设备。并且主编号一般和驱动相关联,可以说明我们的驱动的编号为249.
测试我们的字符设备以及驱动,显示查看scull0里面的内容,发现什么都没有,然后把当前登录账户的信息输入到scull0中,再次查看可以看到我们的之前输入的信息。
然后进行模块的卸载,可以发现,相应的设备已经被删除了,同时模块也已经成功卸载了。