linux 驱动开发-模块的构建

1.模块的含义

linux 是采用模块化的方式构建的,允许内核在运行时动态地向其中插入或从中删除代码,这些代码(包扩函数,数据,模块入口函数,模块出口函数)被一并组合

在一个单独的二进制镜像,就是所谓的可装载内核模块。

模块可以是基本的内核镜像尽可能小,同时可以方便地对新功能进行调试,还可以实现热插拔(后续会学习如何实现设备的热插拔功能,暂时无需深究),和内核的核心子系统不一样,模块文件需要有入口点和出口点。

模块与应用程序的区别:

a.模块和库函数类似,一个模块通常包含若干函数和数据,每个函数提供特定的服务,决定完成哪些功能则是应用程序的事情,模块只是用来为应用程序提供服务。也就是策略与机制的关系。模块提供机制,应用程序根据模块提供的机制实现策略。

b.模块的注册函数只是把模块注册到内核中,模块中的函数如何被调用是应用程序的事情。

c.应用程序退出是可以不管资源的释放和其他清理工作(通常我们还是会处理),但模块的退出函数必须仔细撤销初始化函数所作的一切。

d.模块被链接到内核,它只能调用哪些被内核导出的函数(以后会讲到如何导出内核函数),使用的头文件是内核源代码中include/目录下的头文件,如:

#include<linux/init.h>   ======>include/linux/init.h

e.模块不会和任何库链接

f.模块编程必须慎重考虑并发问题,通常必须是可重入的。

2.模块的编译,装载和卸载。

请参考linux内核稳定,有非常详细的描述。

Documentation/kbuild/modules.txt

因为文档是英文,我简单描述一下。

a.首先运行makefile编译模块,简单分析make的编译参数

make -C  将目录改变到内核源代码所在目录,其中有内核的顶层makefile文件,

M=‘pwd’  要求顶层makefile在构造modules目标之前返回到模块的源代码目录。

modules 只想obj-m变量中设定的模块,就是告诉编译系统,此make 是要编译一个内核模块。

内核转载和卸载的命令

insmod

46 通过insmod将模块的代码和数据安装到系统正在运行的内核中。一旦安装成功,则模块就可以访问内核的公共符号(包括函数和变量)。insmod和ld类似,但insmod不

会修改模块的磁盘文件,只会修改内存中的副本。

rmmod

通过rmmod卸载模块,注意,只有root权限才可以安装和卸载模块。如果内核认为模块仍然处于使用状态,有可能无法卸载。在编译内核时需要将Loadable module s    upport-->Module unloading选中,否则内核不支持模块卸载。

lsmod

lsmod程序列出了当前装载到内核中的所以模块,还列出了其他信息,如其他模块是否在使用某个特点模块。lsmod通过读取/proc/modules获得这些信息。

上面的基本知识大家有个大概的印象即可,下面示例分析一下,一些程序学习的起源都是Hello world, 那么我们也从Hello world开始,创建一个简单的Hello world 模块。

首先构建模块编译的makefile文件

#Makefile
obj-m = hello.o

KERN = /share/arm/linux-3.2                               #基于源代码树的模块编译,源代码树必须要先编译完成后,才能进行模块编译
# KERN = /lib/modules/`uname -r`/build/                   ##如果你在x86平台的linux系统,直接可以编译基于x86平台的模块

all:
        make -C $(KERN) M=`pwd` modules

clean:
        make -C $(KERN) M=`pwd` modules clean
        rm -rf modules.order

看看首个模块代码helloWorld.c

#include <linux/init.h>
#include <linux/module.h>
//模块必须的两个头文件
MODULE_LICENSE("GPL");      //GPL协议要求
MODULE_AUTHOR("MJ");   //option       描述作者信息
MODULE_DESCRIPTION("just for test");   //option  描述模块的

static __init int hello_init(void)
{
    printk(KERN_EMERG,"hello kernel !\n");    //printk 类似应用程序的printf, 用法稍有不同,可百度一下。
}

static __exit void hello_exit(void)
{
   printk(KERN_EMERG,"bye, cruel world!\n");
}

module_init(hello_init);
module_exit(hello_exit);

通常printk不能直接输出到终端,需要看终端的配置及你printk的打印机别。 但是一定会输出到log文件,你可以用dmesg 命令查看log message。

printk()

a.介绍

printk是内核中非常好用的一种信息输出方法,和printf很象,不同的是printk可以附加不同的日志级别,从而可以根据消息的严重程度分类。如:

printk(KERN_DEBUG "Here I am: %s:%i\n", __FILE__, __LINE__);

b.日志级别

printk()定义在/kernel/printk.c中,消息级别和原型声明都在<linux/kernel.h>中。缺省级别在printk.c中指定。

支持的日志级别:

KERN_EMERG: 紧急情况

KERN_ALERT: 需要立即被注意到的错误

KERN_CRIT: 临界情况

KERN_ERR: 错误

KERN_WARNING: 警告

KERN_NOTICE: 注意

KERN_INFO: 非正式的消息

KERN_DEBUG: 调试信息(冗余信息)

c.printk向用户空间的输出

两个守护进程syslogd和klogd用于处理日志信息。小于控制台级别的信息会被输出到console,而大于控制台级别的信息不输出,只是写入/var/log/messages和/proc/kmsg中。可以通过dmesg查看。

修改控制台级别:

$>echo 8 > /proc/sys/kernel/printk

$>klogd -c 8

/*需要先关闭klogd,用ps -C klogd 查出这个进程的pid,然后kill)

printk函数将消息写到一个长度为__LOG_BUF_LEN字节的循环缓冲区中,然后唤醒任何睡眠在syslog系统调用或正在读取/proc/kmsg的进程。循环缓冲区满了以后,会绕>回开始处填写新的内容。printk()可以在中断中调用。

当printk()的调用频率过高时,还可以通过printk_ratelimit()限制输出。

(7)模块的初始化和清除

<linux/init.h>中包含了和模块的初始化和清除相关的信息。

初始化

a.module_init

用于注册模块的初始化函数

module_init(hello_init);

b.__init

用于修饰模块的初始化函数,表明该函数只在模块的初始化期间使用。初始化完成后,这个函数所占的内存会被释放。

static int __init hello_init(void)

{

...

}

c.__initdata

用于修饰模块的初始化数据结构。

int __initdata array[100];

清除

a.module_exit

用于注册模块的清除函数

module_exit(hello_exit);

b.__exit

static void __exit hello_exit(void)

{

...

清除函数没有返回值,被__exit修饰的模块只能用于模块卸载(编译器会把该函数放在特殊的ELF段中),其他时候调用清除函数都是错的。

本文对linux 模块进行基本的介绍,让大家对linux模块有个基本的认识。

下一篇文章将对模块的其他特性进行讲解

linux 驱动开发-模块的构建

时间: 2025-01-01 22:45:12

linux 驱动开发-模块的构建的相关文章

linux驱动开发-模块驱动

linux内核是可以高度定制的,通过配置编译选项达到定制的目的. 在配置kernel编译选项时驱动程序的编译选项一般有三种,不编译.编译为内核驱动.编译为模块驱动.所以linux驱动一般分为两类,内核驱动和模块驱动,当然这两者之间并无绝对区别:当编译为内核驱动时,驱动程序将会随内核一起运行,就相当于内核的固有部分一样:当编译为模块驱动时,每个驱动程序都是独立的个体,在需要的时候安装,用完了再卸载,可以节约硬件资源.以下内容描述的是模块驱动的开发过程. 1.获取内核源码,按照目标器件(PC机或者开

嵌入式linux驱动开发之给你的linux系统添加温度传感器模块

忙了几天,终于可以让ds18b20在自己的开发板的linux系统上跑了!虽然ds18b20不是什么新鲜玩意,但是想想知己可以给linux系统添加模块了还是有点小鸡冻呢! 虽然说现在硬件的资源非常丰富而且剩余很多,可以用软件资源来代替硬件资源,比如说可以用视频编解码软件取代硬件来工作.但有很多模块需要实时的采集数据这都是软件永远无法代替的,而且随着互联网的进一步发展,智能化也是一个必然的趋势,因此大量的传感器和控制芯片将被应用到生产生活中,所以个人觉得驱动开发还是个不错的方向.同时,作为学习者,再

【转】linux驱动开发的经典书籍

原文网址:http://www.cnblogs.com/xmphoenix/archive/2012/03/27/2420044.html Linux驱动学习的最大困惑在于书籍的缺乏,市面上最常见的书为<linux_device_driver 3rd Edition>,这是一本很经典的书,无奈Linux的东东还是过于庞大,这本侧重于实战的书籍也只能停留在基本的接口介绍上,更深入的东东只能靠我们自己摸索了.但万事总有一个开头,没有对Linux驱动整体框架的把握是很难做一个优秀的驱动开发者的.除了

Linux 驱动开发笔记(一)

1.查看printk函数日记输出 (1)使用字符终端:通常使用ctrl+alt+f1切换查看: (2)使用cat /proc/kmsg命令:(在Linux系统启动后,/proc/kmsg文件可以查看内核对外所用的符号表,可以用cat命令查看器内容.) (3)使用dmesg命令查看. linux/kernel.h文件定义的printk函数的Log Level: 常数定义语句 意义 #define KERN_EMERG "<0>"/*系统不运行*/ #define KERN_A

s3c6410 Linux 驱动开发环境搭建

s3c6410 Linux 驱动开发环境搭建 -- 既然你是做Linux开发的,你还用虚拟机? 非常多人都在win下做开发,于是SD_writer.exe之类的烧写工具"大行其道",多是用虚拟机Linux. 全然转到Linux下学习開始蛮不爽的,开发板制作商送的教程都是些讲Win-CE的东东,感觉实质性的东西没什么.对于全然用Linux做开发的技术解说非常少,连烧写SD卡都用的win以下的程序.后来找了些资料,整理在这里,希望留给有心人.共同营造一个更好的共同学习的环境. 当别人遇到困

驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED

这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的住,不然真像一些人说的,学了一年嵌入式感觉还没找到门. 不能再扯了,涉及到linux的驱动开发知识面灰常广,再扯文章就会变得灰常长.首先还是回到led驱动的本身上,自从linux被移植到arm上后,做驱动开发的硬件知识要求有所降低,很多都回归到了软件上,这是系统编程的一大特点,当然 ,也不排除有很多

嵌入式linux驱动开发之点亮led未遂(驱动编程思想之初体验)

有了上两篇文章的基础,我们就可以开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的住,不然真像一些人说的,学了一年嵌入式感觉还没找到门. 另外实践很重要,一年多以前就知道了arm,那时整天用单片机的思维去yy着arm,直到前段时间弄来一块arm板,烧上linux系统后才知道,坑呀!根本不是那回事,所以实践是学习计算机类最重要的基本素质,如果整天看书,那基本上

linux驱动开发流程

嵌入式linux驱动开发流程嵌入式系统中,操作系统是通过各种驱动程序来驾驭硬件设备的.设备驱动程序是操作系统内核和硬件设备之间的接口,它为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,可以像操作普通文件一样对硬件设备进行操作.设备驱动程序是内核的一部分,完成以下功能:◇ 驱动程序的注册和注销.◇ 设备的打开和释放.◇ 设备的读写操作.◇ 设备的控制操作.◇ 设备的中断和轮询处理.Linux主要将设备分为三类:字符设备.块设备和网络设备.字符设备是指发送和接收数据以字符的

嵌入式Linux驱动开发实战教程

嵌入式Linux驱动开发实战教程(内核驱动.看门狗技术.触摸屏.视频采集系统) http://www.ibeifeng.com/goods-475.html 咨询QQ2110053820 课程讲师:韩老师 课程分类:Linux 适合人群:高级 课时数量:109课时 更新程度:完成 用到技术:嵌入式 Linux 涉及项目:驱动开发.看门狗技术.触摸屏.视频采集 课程简介:    嵌入式软件开发无疑是当今最热门的行业,嵌入式软件工程师的薪资比普通的软件工 程师的薪资平均高50%以上.随着智能控制.物