Linux驱动开发(一).doc

上传人:pu****.1 文档编号:547632342 上传时间:2022-09-18 格式:DOC 页数:6 大小:125.50KB
返回 下载 相关 举报
Linux驱动开发(一).doc_第1页
第1页 / 共6页
Linux驱动开发(一).doc_第2页
第2页 / 共6页
Linux驱动开发(一).doc_第3页
第3页 / 共6页
Linux驱动开发(一).doc_第4页
第4页 / 共6页
Linux驱动开发(一).doc_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《Linux驱动开发(一).doc》由会员分享,可在线阅读,更多相关《Linux驱动开发(一).doc(6页珍藏版)》请在金锄头文库上搜索。

1、 Linux驱动开发(一)引言:学习Linux驱动先从模块开始,驱动都是以模块的形式出现的,所以编写内核模块是学习驱动的第一步。下面以一个实例来展开模块的开发。1. 新建一个文件夹,mkdir driver2. 写一个。C文件,vim hello.c3. 加入代码/这两个头文件时开发模块必须的两个头文件#include #include MODULE_LICENSE(GPL); /通过GPL来授权,是一个授权声明,linux内核维护是开源组织维护的,对于你编写的每一个驱动都是贡献于开源组织的,是用来扩展内核的,而不是来污染内核的,linux内核对函数使用是有要求的,没有通过授权的不能使用这些函

2、数。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_exi

3、t); / 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

4、下一行为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 /卸载模块查

5、看模块是否加载成功用命令dmesg,输出结果,如图:7. 当模块已经加载后,再重新加载一遍便会出现文件存在的提示,加载之后不能再进行加载。要消除这个提示,除非用rmmod命令将其卸载掉,然后再重新加载,加载完毕后用lsmod命令查看新加载的模块,一般新加载的模块都在最上面,如图:也可以通过查看proc/modules下文件按查看,如图:8. 命令modinfo hello.ko可以查看模块的详细信息9. 加载模块的目的是为了初始化设备,有时初始化时需要传递参数,下面介绍模块中如何传递参数。可以通过module_param为模块定义一个参数,在装载内核模块时,用户可以向模块传递参数,参数类型可以

6、是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向模块传递

7、参数定义参数/可读可写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文件夹,可以看到parame

8、ters的文件夹进入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,结果如下,会产生wa

9、rning,看起来没什么错,但重新加载就会出错重新加载hello模块,就会出错,如图:利用dmesg命令可查看结果,不知道的plus,可以看出无法识别的plus,可以看出模块之间是不能互相调用函数。那么如何解决这个问题呢?修改symbol.c文件,vim symbol.c,增加EXPORT_SYMBOL(plus);修改Makefile,如图:如下:将obj-m :=symbol.o修改完毕执行make,重新加载insmod symbol.ko在重新加载hello.ko,可以看到可以调用其他模块的函数了,注意:如果出现加载时文件重复,卸载即可。重新加载后的结果,如图:总结:如果你想调用另外一个模块的函数,必须在另外一个模块的函数中加EXPORT用lsmod查看模块,可以看到最上面的新加载模块hello和symbol,还能看到symbol被hello引用。如果要卸载的话,必须先卸载hello再卸载symbol,如果先卸载symbol的话会有提示symbol is use by hello

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号