Linux驱动开发(一).doc_第1页
Linux驱动开发(一).doc_第2页
Linux驱动开发(一).doc_第3页
Linux驱动开发(一).doc_第4页
Linux驱动开发(一).doc_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux驱动开发(一)引言:学习Linux驱动先从模块开始,驱动都是以模块的形式出现的,所以编写内核模块是学习驱动的第一步。下面以一个实例来展开模块的开发。1. 新建一个文件夹,mkdir driver2. 写一个。C文件,vim hello.c3. 加入代码/这两个头文件时开发模块必须的两个头文件#include #include MODULE_LICENSE(GPL); /通过GPL来授权,是一个授权声明,linux内核维护是开源组织维护的,对于你编写的每一个驱动都是贡献于开源组织的,是用来扩展内核的,而不是来污染内核的,linux内核对函数使用是有要求的,没有通过授权的不能使用这些函数。int hello_init(void) /对于入口函数没参数,但有返回值 printk( hello modulen); /注意:与hello module之间要有空格 /printf和printk就一个差别,能否设定级别 “”就是设定级别为最高级别0 return ;int hello_exit(void) /出口函数,没参数,没返回值 printk(hello exitn);MODULE_AUTHOR(“tocore”); /注明模块的作者module_init(hello_init); /module_init是一个宏,里面加载的是入口函数module_exit(hello_exit); / module_exit是一个宏,里面加载的是出口函数4. 以上就是一个模块文件,写完后要进行编译,编译之前必须要写Makefile文件才能编译。Makefile文件如下:ifeq ($(KERNEKRELEASE),) /这是内核中定义的一个宏,编译模块时,如果KERNEKRELEASE为空时,则说明要编译的模块不在内核中,$表示取变量KERNELDIR :=/usr/src/kernels/2.6.18-92.el5-xen-i686 /通过KERNELDIR得到内/核地址,中间是tab键PWD :=$(shell pwd) /得到当前模块路径,default: /default下一行为tab键 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules /最前面为一tab键 /-C后面跟的内核路径,这句话的意思是调用make命令时切换当前目录到KERNELDIR下面,去编译PWD目录下的模块,M的意思是模块,M=$(PWD) modules,当前目录下的模块else obj-m :=hello.o /目标文件为hello.oendif5. 执行make命令对模块进行编译6. 如何加载和卸载模块到内核中利用insmod命令加载,利用rmmod命令卸载具体用法为:insmod hello.ko /加载模块 rmmod hello.ko /卸载模块查看模块是否加载成功用命令dmesg,输出结果,如图:7. 当模块已经加载后,再重新加载一遍便会出现文件存在的提示,加载之后不能再进行加载。要消除这个提示,除非用rmmod命令将其卸载掉,然后再重新加载,加载完毕后用lsmod命令查看新加载的模块,一般新加载的模块都在最上面,如图:也可以通过查看proc/modules下文件按查看,如图:8. 命令modinfo hello.ko可以查看模块的详细信息9. 加载模块的目的是为了初始化设备,有时初始化时需要传递参数,下面介绍模块中如何传递参数。可以通过module_param为模块定义一个参数,在装载内核模块时,用户可以向模块传递参数,参数类型可以是byte、short、ushort、int、uint、long、ulong、charp、bool、或invbool(布尔的反),在模块被编译时会将module_param中声明的类型与变量定义的类型进行比较,判断是否一致。module_param(num, int, S_IRUGO | S_IWUGO); S_IRUGO表示可读,S_IWUGO表示可写。#include #include MODULE_LICENSE(GPL);int num=0;/不改动,默认为0,定义参数module_param(num,int,S_IRUGO|S_IWUGO); /利用module_param向模块传递参数定义参数/可读可写int hello_init(void) printk( hello module,num=%dn,num); /打印出数字 return ; Void hello_exit(void) printk(hello exitn);module_init(hello_init);module_exit(hello_exit);用make编译程序,然后利用insmod hello.ko重新装载模块,可以看到num的值被打印出来重新卸载hello模块,rmmod hello.ko重新加载模块,并传入参数:输出参数num=1000进入目录再进入hello文件夹,可以看到parameters的文件夹进入parameters文件夹,可以看到num的值为1000不能通过vi num来修改num的值,只能通过echo 10num来修改num的值为10.10 导出符号的使用 在C程序中文件之间可以互相调用.C文件,模块之间不能互相调用文件,通过导出符号,一个模块就可以调用另一个模块的文件。写一个文件symbol.c文件,文件如下:修改Makefile文件,如下:将obj-m :=symbol.o修改完毕后进行编译,执行make编译编译完毕后加载到内核中 ,如图:修改hello.c文件修改Makefile,将obj-m :=hello.o修改完毕后执行make,结果如下,会产生warning,看起来没什么错,但重新加载就会出错重新加载hello模块,就会出错,如图:利用dmesg命令可查看结果,不知道的plus,可以看出无法识别的plus,可以看出模块之间是不能互相调用函数。那么如何解决这个问题呢?修改symbol.c文件,vim symbol.c,增加EXPORT_SYMBOL(plus);修改Makefile,如图:如下:将obj-m :=symbol.o修改完毕执行make,重新加载insmod symbol.ko在重新加载hello.ko,可以看到可以调用其他模块的函数了,注意:如果出现加载时文件重复,卸载即可。重新加载后的结果,如图:总结:如果你想调用另外一个模块的函数,必

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论