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

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

相关文章推荐

汇编bne的问题 汇编中的标号1: 以及bne 1b解释

下面一段程序摘自《嵌入式Linux应用开发完全手册》page-95 memsetup:     @ 设置存储控制器以便使用SDRAM等外设     mov r1,     #MEM_CT...

S3C2440开发工具realview MDK4.22之库的使用

一。与c库会强制链接 如果你写了一个c程序,必然会和c库链接,尽管你没有直接使用c库函数。这是因为编译器为了改进程序,可能隐含的产生了对c库函数调用。 即便你的程序没有main()函数,也只是说c...
  • sam1430
  • sam1430
  • 2011年11月17日 16:26
  • 2775

"手把手教你学linux驱动开发”OK6410系列之01---模块编程

一、实验环境  开发机环境           操作系统:ubuntu 9.10           交叉编译环境:arm-linux-gcc 4.2.2 ,安装位置 /usr/local/ar...

linux驱动开发模块中Makefile的理解

本文系转载,转载自:http://lzw.me/Category/learning/linux-driver-dev-makefile.html | 志文工作室   对于一个简单的驱动模块,以下为...
  • shen924
  • shen924
  • 2013年05月26日 22:30
  • 520

手把手教你学linux驱动开发”OK6410系列之01---模块编程

一、实验环境  开发机环境 操作系统:ubuntu 9.10 交叉编译环境:arm-linux-gcc 4.2.2 ,安装位置 /usr/local/arm/4.3.2/ 6410板子内核源码...

“手把手教你学linux驱动开发”OK6410系列之01---模块编程

一、实验环境  开发机环境           操作系统:ubuntu 9.10           交叉编译环境:arm-linux-gcc 4.2.2 ,安装位置 /usr/local/ar...

“手把手教你学linux驱动开发”OK6410系列之01---模块编程 .

一、实验环境  开发机环境           操作系统:ubuntu 9.10           交叉编译环境:arm-linux-gcc 4.2.2 ,安装位置 /usr/local/ar...

LINUX驱动开发系列1 —— 内核模块

这是本小白的系列LINUX内核学习过程的开篇,本小白尽量把自己学习中遇到的问题和理解用白话解释给大家。希望大家在LINUX驱动开发的道路上走的更顺利一点。如转载,请注明来源,谢谢! 开篇讲LINUX...

“手把手教你学linux驱动开发”OK6410系列之01---模块编程

一、实验环境  开发机环境           操作系统:ubuntu 9.10           交叉编译环境:arm-linux-gcc 4.2.2 ,安装位置 /usr/local/ar...

linux驱动开发:lcd模块简介

作为人机交互的display界面,lcd屏幕一直扮演着很重要的角色。试想一下,如果你的电子设备没有显示屏,那么人机交互将变成什么样的?比如说手机~ 一般情况,LCD屏需要驱动器和控制器。拿51单片机...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux驱动开发①--Linux基础及hello模块
举报原因:
原因补充:

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