Linux驱动开发①--Linux基础及hello模块

原创 2017年01月03日 16:55:04

       驱动程序是系统的重要组成部分,Linux中所有对硬件的的操作都是基于驱动程序的。驱动程序可以直接编译进内核也可以使用module的方式手动添加到内核之中,为了学习方便,我将使用模块module的方式将模块加载到内核。

       编写驱动的第一步是搭建环境,我有一台运行Ubuntu16的虚拟机,可以直接在Ubuntu上进行驱动模块的编写工作,因为Ubuntu下已经有完整的Linux源代码和头文件,在目录/lib/modules/和/usr/src/下,具体不知道两个目录的区别,可能是通过连接文件的链接功能使得最终两个目录的文件其实是一样的。源码目录下有多个文件夹,表示多个不同的Linux内核版本,需要选择与机器匹配的内核版本才能保证编译出来的模块可以正确使用,查看本机的Linux内核版本的方法为:uname -r,出现机器内核版本,例如我的机器为“4.4.0-53-generic”,这样选择源码目录的时候就需要指定4.4.0-53-generic版本。假如,虽然我没有遇到过,机器中没有找到源码,可以从Linux官方网站上下载对应内核版本的Linux源码包,这个源码包就可以作为模块编写的环境了。有了源码路径之后基本上就算搭建好了模块设计的开发环境了,因为我不是使用交叉编译,我是在本机上进行模块设计,编写的模块给本机使用,如果是为嵌入式Linux系统编写模块的话需要有嵌入式Linux的源码包和嵌入式Linux的编译器,也就是大名鼎鼎的arm-linux-gcc编译器,关于嵌入式Linux的模块编写以后在说,这里处于学习的目的现在PC电脑上进行实验,需要注意的是树莓派以及类似的运行Debian或者Ubuntu的π都可以直接在本身Linux环境中进行驱动模块的开发,因为它们本身就是一个完整的计算机系统。

       接下来就可以进行驱动模块的编写了,驱动程序的编写和应用程序不同,它没有main函数,只有初始化、释放、操作函数,显得很复杂的样子,但是只要清楚了驱动程序的原理,一切还是很明朗的,至少我是这么想的,虽然我还没很明朗。下面是一个最简单的驱动程序:

#include <linux/init.h>         /* printk() */   
#include <linux/module.h>       /* __init __exit */   
  
static int  __init  hello_init(void)      /*模块加载函数,通过insmod命令加载模块时,被自动执行*/  
{  
  printk(KERN_INFO " Hello World enter\n");  
  return 0;  
}

static void  __exit  hello_exit(void)    /*模块卸载函数,当通过rmmod命令卸载时,会被自动执行*/  
{  
  printk(KERN_INFO " Hello World exit\n ");  
}  
  
module_init(hello_init);  
module_exit(hello_exit);  
  
MODULE_AUTHOR("tangquan");           /*模块作者,可选*/  
MODULE_LICENSE("Dual BSD/GPL");     /*模块许可证明,描述内核模块的许可权限,必须*/  
  
MODULE_DESCRIPTION("A simple Hello World Module");	/*模块说明,可选*/  
MODULE_ALIAS("a simplest module");	/*模块说明,可选*/
       驱动程序源码完成之后就可以进行编译了,这里使用和编译应用程序一样的方法使用Makefile文件自动编译,所以需要先编辑Makefile文件:

obj-m := hello.o
module-objs := hello.o
KDIR :=/lib/modules/4.4.0-51-generic/build/
#KDIR :=/usr/src/linux-headers-4.4.0-53-generic/
PWD := $(shell pwd)
all:      
	$(MAKE)  -C  $(KDIR)  SUBDIRS=$(PWD)  modules  
	@rm -rf *.mod.*  
	@rm -rf .*.cmd  
	@rm -rf *.o  
	@rm -rf Module.*  
clean:  
	rm -rf *.ko
	
obj-m := hello.o表示的是目标文件,这样会生成hello.ko文件。

module-objs := hello.o表示连接的文件。

KDIR表示Linux源码路径。

PWD就是驱动程序的路径。

       运行make就可以进行模块编译了,生成的hello.ko文件就是目标模块,使用insmod安装该模块没有错误表示模块安装成功,使用rmmod可以卸载模块。由于驱动程序中的printk打印的信息不能直接显示在终端上,可以使用 dmesg 查看自开机以来的信息就可以看到printk输出的信息了,使用dmesg | tail可以查看最后的几个消息。

       关于编译模块出错参考上一篇文章:http://blog.csdn.net/tq384998430/article/details/53994637

       Linux驱动编写参考文章:http://www.linuxidc.com/Linux/2011-10/44721.htm

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

Linux驱动模块基础

1、模块加载函数    Linux内核模块加载函数一般以__init标识声明,典型的模块加载函数的形式如下:  static int __init initialization_function(...

linux驱动基础开发2——linux 驱动开发前奏(模块编程)

转自http://blog.csdn.net/xdw1985829/article/details/6832525 一、linux内核模块简介      linux内核整体结构非常...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

linux驱动基础开发2——linux 驱动开发前奏(模块编程)

一、linux内核模块简介      linux内核整体结构非常庞大,其包含的组件也非常多。我们怎么把需要的部分都包含在内核中呢?      一种办法是把所有的需要的功能都编译到内核中。这会导致两...

linux驱动基础开发2——linux 驱动开发前奏(模块编程)

一、linux内核模块简介      linux内核整体结构非常庞大,其包含的组件也非常多。我们怎么把需要的部分都包含在内核中呢?      一种办法是把所有的需要的功能都编译到内核中。这...

《TQ2440加载Hello world驱动模块》

经过将近一个月都时间终于按照手册把Linux内核移植完了,接下来要开始驱动模块的移植了,在网上查了一些资料,总结如下: 目标平台:TQ2440  ARM9 内核版本:Linux-2.6.2...

Linux设备驱动开发基础---Linux内核模块

一、Linux内核模块的程序结构 ●模块加载函数(必须)  当通过insmod或 modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成本模块的相关初始化工作。  ●模块卸...

Linux驱动开发基础

Linux驱动开发基础 驱动分类 常规分类法 1、  字符设备 字符设备是一种按字节来访问的设备,字符驱动则负责驱动字符设备,这样的驱动通常实现open,close,read和write系统调...

Linux驱动基础 内核模块

Linux设备驱动是以内核模块的形式出现,所以,学会编写Linux内核模块编程是学习Linux设备驱动的必要步骤 Linux内核模块的存在原因和作用 Linux内核的整体架构非常庞大,其包含的组件...

Linux设备驱动--Hello World模块

从学习C语言开始,我们的第一个例子总是以hello world来说明,同样,学习Linux设备驱动开始从Helllo World开始! hello world 模块 #include #incl...

Linux 2.6内核驱动之hello模块

终于开始在钟爱的Linux上学习写驱动程序了。本来以为写一个hello模块是异常简单的事情,结果折腾了几天才编译通过。首先为了测试安装了虚拟机(内核程序是很危险滴,我可不想让自己的爱本频繁崩溃),装f...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)