NUC972----最简单的驱动(转)
1.新建文本文档,重命名为 hello_dev.c (驱动的开发同应用的开发一样,也是在文本文档下开发的)。
2.包含头文件
内核模块需要包含内核相关头文件,不同模块根据功能的差异,所需要的头文件也不相同,但是<linux/module.h>和<linux/init.h>是必不可少的。
|
#include <linux/module.h> #include <linux/init.h> |
3.模块初始化
模块的初始化负责注册模块本身。如果一个内核模块没有被注册,则其内部的各种方法(函数)无法被应用程序使用,只有已注册模块的各种方法才能够被应用程序使用并发挥各方法的实际功能。模块并不是内核内部的代码,而是独立于内核之外,通过初始化,能够让内核之外的代码来替内核完成本应该由内核完成的功能,模块初始化的功能相当于模块与内核之间衔接的桥梁,告知内核“我进来了”。
|
static int __init module_init_func(void) { 初始化代码 } module_init(module_init_func); |
说明:
(1) 模块初始化函数一般都需声明为 static,因为初始化函数对于其它文件没有任何意义;
(2) __init 表示初始化函数仅仅在初始化期间使用,一旦初始化完毕,将释放初始化函数所占用的内存,类似的还有__initdata;
(3) module_init 是必须的,没有这个定义,内核将无法执行初始化代码。module_init宏定义会在模块的目标代码中增加一个特殊的代码段,用于说明该初始化函数所在的位置。
当使用 insmod 将模块加载进内核的时候,初始化函数的代码将会被执行。模块初始化代码只与内核模块管理子系统打交道,并不与应用程序交互。
4.模块退出。
当系统不再需要某个模块,可以卸载这个模块以释放该模块所占用的资源。模块的退出相当于告知内核“我要离开了”。实现模块退出的函数常称为模块的退出函数或者清除函数
|
static void __exit module_exit_func(void) { 模块退出代码 } module_exit(module_exit_func); |
说明:
(1) 模块退出函数没有返回值;
(2) __exit 标记这段代码仅用于模块卸载;
(3) module_exit 不是必须的。但是,没有 module_exit 定义的模块无法被卸载,如果需要支持模块卸载则必须有 module_exit。
当使用 rmmod 卸载模块时,退出函数的代码将被执行。模块退出代码只与内核模块管理子系统打交道,并不直接与应用程序交互。
5.许可证
Linux 内核是开源的,遵守 GPL 协议,所以要求加载进内核的模块也最好遵循相关协议。为模块指定遵守的协议用 MODULE_LINCENSE 来声明,如:
|
MODULE_LICENSE("GPL"); |
内核能够识别的协议有“GPL”、“GPL v2”、“GPL and additional rights(GPL 及附加权利)”、“Dual BSD/GPL(BSD/GPL 双重许可)”、“Dual MPL/GPL(MPL/GPL 双重许可)”以及“Proprietary(私有)”。
如果一个模块没有指定任何许可协议,则会被认为是私有协议。采用私有协议的模块,在加载过程中会出现警告,并且不能被静态编译进内核。
执行完上面步骤,一个最小的linux驱动便写好了。全部代码如下:
6.编译
内核模块的编译需要Makefile文件,在hello_dev.c所在路径建立Makefile文件:
在Makefile输入以下文本并保存。
|
obj-m := hello_dev.o PWD := $(shell pwd) KVER ?= $(shell uname -r) KDIR :=/home/qlqcetc/nuc970bsp/02.linux内核3.10.x all: $(MAKE) -C $(KDIR) M=$(PWD) clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions |
其中obj-m 指定要编译的源文件是hello_dev.c,KDIR指定内核的路径,驱动模块的编译是需要内核源码的相关文件的,所以需要设置内核源码所在路径。
中断进入驱动源码所在文件夹:
#/home/qlqcetc/nuc970bsp/06.示例驱动程序/00.hello_dev
#ls
编译:
#make
#ls
生成的hello_dev.ko就是驱动模块,使用U盘将其复制到开发板的/lib/modules/路径下(modules文件夹需要创建),就可以加载驱动模块了。
开发板终端输入:
# cd /lib/modules/
# insmod hello_dev.ko
可以看到驱动加载成功,驱动打印出信息:
开发板终端输入:
# mkdir 3.10.101
# rmmod hello_dev.ko
可以看到驱动卸载成功,驱动打印出信息:
NUC972----最简单的驱动(转)的更多相关文章
- NTDDK 从两个最简单的驱动谈起
第 1 章 从两个最简单的驱动谈起 Windows 驱动程序的编写,往往需要开发人员对 Windows 内核有深入了解和大量的内 核调试技巧,稍有不慎,就会造成系统的崩溃.因此,初次涉及 Window ...
- 设计的MOS管三极管简单开关电路驱动能力不够2
设计的MOS管三极管简单开关电路驱动能力不够 [复制链接] lxizj 9 主题 454 帖子 1783 积分 四级会员(40) 积分 1783 发消息 16# 发表于 2012-4-23 ...
- ubuntu下简单的驱动编译
转自:http://www.eefocus.com/jefby1990/blog/13-02/291628_c39b8.html 本文是参考了网上多篇帖子而写的算不上什么原创.唯一值得欣慰的只不过在本 ...
- MongoDB简单使用 —— 驱动
C#中可以通过官方的驱动MongoDB.Drvier来使用,使用Nuget安装即可. Install-Package MongoDB.Driver Bson文档操作: using MongoDB.Bs ...
- 用.netcore写一个简单redis驱动,调试windows版本的redis.平且给set和get命令添加参数.
1. 下载windows版本的redis 2.开发环境vs2017 新建一个 .net core控制台. private static Socket socket = new Socket(Addr ...
- windows driver 简单的驱动和通信
sysmain.c #pragma once #pragma warning(disable: 4100) #include <ntifs.h> #include <ntddk.h& ...
- 设计的MOS管三极管简单开关电路驱动能力不够3
16楼说得非常明白,补充一点,R3如果不要,会有下冲产生.4 Q: Z/ G G1 s8 Z- } 能解释下为什么会产生过冲吗?9 i, P* D* X) u. t/ b ^ 让我们这些菜鸟学习学 ...
- 设计的MOS管三极管简单开关电路驱动能力不够1
您需要 登录 才可以下载或查看,没有帐号?注册 x . ?& P' U5 r/ ~& `: B 用AOD409设计的开关电路为什么驱动能力不够,请大家帮忙分析一下原因啊.这个电路作用就 ...
- [下载] MultiBeast 6.2.1版,支持10.9 Mavericks。Mac上的驱动精灵,最简单安装驱动的方式。
下载地址1:http://pan.baidu.com/s/1i3ier9F 下载地址2:http://www.tonymacx86.com/downloads.php?do=cat&id=3 ...
随机推荐
- JDBC(4)—Preparedstatement
功能:使用PreparedStatement操作数据表,其功能与Statement一致,但为何要使用PreparedStatement呢. 一.原因: 1.使用sql语句进行操作数据表时,需要拼写sq ...
- git代码合并:Merge、Rebase的选择
代码合并:Merge.Rebase的选择 Zhongyi Tong edited this page on Dec 7, 2015 · 3 revisions Pages 19 Home 2.1 快速 ...
- css3 transition属性实现3d动画效果
transition属性是一个很强大的3d动画属性,我动手试了一下,很多在网上很火的网页动画都可以用这个属性实现,只能说这个属性是在是太强大啦,本人在学习次属性之后才知道自己对css3的认识还是偏少, ...
- SpringMVC核心分发器DispatcherServlet分析
本文将分析SpringMVC的核心分发器DispatcherServlet的初始化过程以及处理请求的过程,让读者了解这个入口Servlet的作用. DispatcherServlet初始化过程 在分析 ...
- Dubbo的使用入门
一.包引入 1.父模块pom.xml中加入依赖: <!-- dubbo --> <dependency> <groupId>com.alibaba.boot< ...
- 使用go语言操作db2
操作系统 : CentOS7.3.1611_x64 go语言版本:1.8.3 linux/amd64 db2版本: db2_v101_linuxx64_expc 问题描述 怎么使用go语言在CentO ...
- java的两种同步方式, Synchronized与ReentrantLock的区别
java在编写多线程程序时,为了保证线程安全,需要对数据同步,经常用到两种同步方式就是Synchronized和重入锁ReentrantLock. 相似点: 这两种同步方式有很多相似之处,它们都是加锁 ...
- codeblocks技巧收集
Ctrl+Shift+C 注释代码块 Ctrl+Shift+X 取消注释
- 【SqlServer】解析SqlServer中的事务
目录结构: contents structure [+] 事务是什么 控制事务 数据并发访问产生的影响 事务的隔离级别 锁 NOLOCK.HOLDLOCK.UPDLOCK 死锁分析 在这篇Blog中, ...
- 12C -- ORA-65048 ORA-65048
创建common user的时候报错: $ sqlplus '/as sysdba' SQL*Plus: Release 12.2.0.1.0 Production on Tue Apr 18 11: ...