linux驱动之hello_world源码与编译

开始了linux驱动的学习,从最简单的hello world开始。

一、hello world源码及注释如下所示:

#include <linux/init.h>  /*必须的头文件,用于初始化和清除函数的头文件*/

#include <linux/module.h>  /*必须的头文件,含有装载模块需要的大量符合和函数的定义, 必须包含在模块源代码中*/

MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("TX_fpga");

MODULE_DESCRIPTION("Hello world test");

MODULE_VERSION("V1.0");

static int __init hello_init(void)    //初始化函数

{

printk(KERN_ALERT "Hello.......................world!\n"); /*这里是初始化代码*/

return 0;

}

static void __exit hello_exit(void)  //清除函数

{

printk(KERN_ALERT "Goodbye,cruel world!\n"); /*清除代码*/

}

module_init(hello_init); #用于指定模块初始化的宏

module_exit(hello_exit);#用于指定模块清除函数的宏

注解:

(1)所有的代码中都包含代码中的两个头文件

(2)MODULE_LICENSE("Dual BSD/GPL");  是一个特殊的宏,用来告诉内核该模块采用的许可证,所有模块应该都包含的。如果没有这样的声明,内核在装载该模块时就会被被“污染”。"Dual BSD/GPL (BSD/GPL双重许可)"、"Dual MPL/GPL (MPL/GPL双重许可)"、"GPL v2 (GPL版本2)"、"GPL and additional rights (GPL及附加权利)"以及"Proprietary (专有)",像PCIE驱动中使用的MODULE_LICENSE("Avnet Design Services");

(3)还可以在模块中包含其他描述性定义,如上所述等,如PCIE驱动中的MODULE_DEVICE_TABLE(pci, ads_pcie_dma_ids);用来告诉用户空间模块所支持的设备。

(4)初始化函数在模块被装载到内核时调用,被声明为static,因为这种函数在特定文件之外没有任何其他意义。__init对内核来讲是一种暗示,表明该函数仅在初始化期间使用。在模块被装载之后,模块装载器就会将初始化函数扔掉,这样可将该函数占用的内存释放出来。模块初始化函数的任务是为以后调用模块函数预先做准备,就像模块在说:我在这儿,并且我能做这些工作。

(5)函数printk()在Linux内核中定义,功能和标准C库中的函数printf类似,内核需要自己单独的打印函数,这是因为它在运行时不能依赖于C库。模块能够调用printk()是因为在insmod函数装入模块后,模块就连接到了内核,因而可以访问内核的公用符号(包括函数和变量)。代码中的字符串KERN_ALERT定义了这条消息的优先级。

(6)module_init()的使用时是强制的。这个宏会在模块的目标代码中增加一个特殊的段,用于说明内核初始化函数所在的位置。没有这个定义,初始化函数用于不会被调用。

(7)每个模块都会需要一个清除函数,在模块被卸载时调用,告诉内核:我要离开啦,不要再让我做任何事情了。清除函数要撤销初始换函数所做的一切。清除函数没有返回值,被声明为void。__exit标记该代码仅用于模块卸载。如果一个模块未定义清除函数,则内核不允许卸载该模块。

(8)module_exit()声明对于内核找到模块的清除函数是必需的。

二、hello world编译:

编译器:gcc

编译命令工具:GNU make

编译文件:Makefile

Hello world的makefile文件:

obj-m := hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean

注解:

(1)第一行中:=表示对变量赋值,此句要表达的是有一个内核模块需要从目标文件hello.o中构造,构造的模块名为hello.ko。

(2)第二行对KDIR变量赋值,该变量指代内核源码目录。

(3)第三行是对PWD变量的赋值,作用是将$(shell pwd)的返回结果即当前目录赋值给PWD,用来指代我们要编译的驱动程序所在的位置。”$”表示调用后面的变量。

(4)第四行和第五行为makefile的规则,all为规则目标也是终极目标,第五行为规则的命令,命令行必须以[TAB]字符开始,[TAB]字符告诉make此行是一个命令行。-C选项的作用是将当前工作目录转移到所指定的位置,即内核的构造树,先执行该路径下的makefile,定位内核的源代码目录。”M=”选项的作用是:当用户需要以某个内核为基础编译一个外部模块的时候,需要在make modules命令中加入”M=dir”,程序会自动跳到所指定的dir(即工程所在的目录)中查找模块源码,将其编译,modules目标文件指向obj-m变量中设定的模块,即hello.o(中间文件),最后生成hello.ko文件。

(5)第六行和第七行是一个清除命令,执行该命令时之前生成的文件都被清除掉。

如上所述,在shell命令解析器中输入make命令生成hello.ko文件。

三、hello world装载与卸载

1.模块装载与查询:

注解:

(1)insmod后面的./不可以省略,表示在当前目录下查找hello.ko文件,如果不加上,insmod不会在当前目录找,最终的结果就是找不到。

(2)lsmod命令用来查询已经添加的内核模块。

(3)装载之后的打印信息在系统日志文件里,/var/log/kern.log中,可以用$ tail /var/log/kern.log命令或$ dmesg命令查看。

2.模块卸载:

时间: 2024-10-03 13:10:07

linux驱动之hello_world源码与编译的相关文章

linux CentOS6.6 i386 源码 cmake 编译mysql 5.5

编译安装MySQL-5.5 搜索下载http://down.51cto.com/ 编译安装MySQL前的准备工作 安装编译源码所需的工具和库 [纯净CentOS 6.6 i386] yum install gcc gcc-c++ ncurses-devel perl wget readline-devel zlib-devel openssl-dev cmake [CMAKE] 指定安装文件的安装路径时常用的选项: -DCMAKE_INSTALL_PREFIX=/usr/local/mysql

Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装

原文:Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装 Linux内核分析(一) 从本篇博文开始我将对linux内核进行学习和分析,整个过程必将十分艰辛,但我会坚持到底,同时在博文中如果那些地方有问题还请各位大神为我讲解. 今天我们会分析到以下内容: 1.      Linux体系结构简介 2.      Linux内核源码简介 3.      Linux内核配置.编译.安装 l  Linux体系结构简介 1.       Linux体系结构(linux系统构成)

【转】Linux CentOS内核编译:下载CentOS源码、编译2.6.32-220的错误(apic.c:819 error &#39;numi_watchdog&#39; undeclared)

一.下载CentOS源码 1.1 查看CentOS版本 cat /etc/issue 1.2 查看Linux内核版本 uname -r 1.3 下载 文件名:kernel-2.6.32-220.el6.src.rpm 下载地址:http://vault.centos.org/6.2/os/Source/SPackages/ 官网:http://vault.centos.org/ 1.4 从kernel-2.6.32-220.el6.src.rpm获取源码 1. rpm -i kernel-2.6

Linux程序包管理--源码编译的原理和基本方法

Linux中使用rpm格式的程序文件包来安装是比较方便的方法, 但是有一部分程序文件包没有rpm包格式, 这时就需要用户自己手工编译源码包来进行安装. 文本主要讲解源码编译的原理和基本操作过程. 源码包命名方式 name - VERSION . tar . gz 其中: VERSION = major . minor . release major表示主版本号, 经过比较大的改进 minor表示次版本号, 改进比较小 release表示对一些bug进行修复 源码包编译过程 源码包是指经过程序员编

马哥linux学习笔记:源码编译安装

由于rpm包在作者制作封装的时候已经把程序的一些特性固定了,如果我们根据自己的需求,需要运用程序的一些没有普适性相关特性,就需要下载程序的源码手动编译安装了,这里只是简单的介绍一下C代码的程序包编译安装方法. 为了能更直观的看到源码编译安装的过程,我演示一下在centos7.2环境中编译安装httpd2.2: 首先,编译的前提是得有称手的工具及环境了,编译c源代码就需要用到开发工具,make,gcc了,环境就需要开发库跟头文件了,如果系统中没有这些,就需要yum安装了. 这里我运行yum gro

Linux CentOS6.5下 源码编译安装MySQL 5.6.16【给力详细教程】

一.编译安装MySQL前的准备工作 安装编译源码所需的工具和库 yum install gcc gcc-c++ ncurses-devel perl 安装cmake,从http://www.cmake.org下载源码并编译安装 wget http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz tar -xzvf cmake-2.8.10.2.tar.gz cd cmake-2.8.10.2 ./bootstrap ; make ; make i

[Android编译(二)] 从谷歌官网下载android 6.0源码、编译并刷入nexus 6p手机

1 前言 经过一周的奋战,终于从谷歌官网上下载最新的android 6.0.1_r62源码,编译成功,并成功的刷入nexus6p,接着root完毕,现写下这篇博客记录一下实践过程. 2 简介 自己下载android系统源码,修改定制,然后编译刷入安卓手机,想想还有点小激动呢.简单点说一句话--定制我们自己的MIUI,这就是android的魅力,这篇博客博主就来教大家实现自己的定制系统. 首先,要明白下面的基础知识: (1) 什么是aosp? aosp就是android open source p

php源码的编译

本片文章主要介绍windows下的php源码的编译. 1.1 编译环境 软件 环境 操作系统 Windows 7 专业版 32bit Visual studio 2012 专业版 PHP 5.5.2.1 线程安全版本 PHP-SDK 下载 1.2 编译步骤 该配置步骤参考PHP官方文档. 1  解压PHP-sdk文件,分别放置于D:/PHP/PHP-sdk/: 2  在PHP-sdk下打开VS2012 x86本机工具命令行提示(该命令行提示符包含了VS的编译.链接等命令的path路径),跳转至P

Linux软件安装之源码安装

什么是源码安装?一开始接触到Linux时候感觉很疑惑,安装不就是跟Windows中安装软件一样,下一步-->更改安装位置-->下一步么,用什么源码安装?现在有了些初步的了解,写出来算是做个笔记,与大家分享学习成果吧. 每个程序开发过程中或因考虑不充分出现一些漏洞,或者有些程序模块是你用不到的, 是否只能程序开发者才能解决问题呢?在Linux中不是这样的,每个人可以根据自己的喜好.要求随意改动源代码,自行修改程序为你所用.这样的源码不必再有专门的安装包,可直接编译安装,这就是源码安装的基本思想.