详细讲解Linux驱动程序

一  编写Linux驱动程序

1.建立Linux驱动骨架

Linux内核在使用驱动时需要装载与卸载驱动

装载驱动:建立设备文件、分配内存地址空间等;module_init 函数处理驱动初始化

卸载驱动:删除设备文件、释放内存地址空间等;module_exit函数处理退出

包含这两个函数的两个宏的C程序文件也可看做是Linux驱动的骨架

2.注册和注销设备文件

任何一个Linux驱动都需要有一个设备文件,否则应用程序将无法与驱动程序交互。

建立设备文件:在第一步编写的处理Linux初始化工作的函数中完成。misc_register函数

删除设备文件:在第一步编写的处理Linux退出工作的函数中完成。misc_deregister函数

3.指定与驱动相关的信息

驱动程序是自描述的,驱动程序的作者姓名、使用的开源协议、别名、驱动描述等信息。这些信息都需要在驱动源代码中指定。

MODULE_AUTHOR、MODULE_LICENSE、MODULE_ALLS、MODULE_DESCRIPION等宏可以指定与驱动相关的信息

4.指定回调函数

一个驱动程序并不一定要指定所有的回调函数,回调函数会通过相关机制进行注册

5.编写业务逻辑

具体的业务逻辑与驱动的功能有关,业务逻辑可能由多个函数、多个文件甚至是多个Linux驱动模块组成

6.编写Makefile文件

Linux内核源代码的编译规则是通过Makefile文件定义的。因此编写一个新的Linux驱动程序必须有一个Makefile文件

7.编译Linux驱动程序

可以直接编译进内核,也可以作为模块单独编译

8.安装和卸载Linux驱动

若将Linux驱动编译进内核,只要Linux使用该内核,驱动程序就会自动转载

若Linux驱动程序以模块单独存在,需使用insmod或modprode命令装载Linux驱动模块,rmmod命令卸载Linux驱动模块

二  第一个Linux驱动,以word_count为例

(一)基础编写代码

#mkdir -p  /root/drivers/ch06/word_count    建立目录存放Linux驱动程序

#cd /root/drivers/ch06/word_count

#echo ‘‘ > word_count.c  建立驱动源代码文件

#echo ‘obj-m := word_count.o‘ > Makefile  编写一个Makefile文件 make命令会吧Linux驱动源代码目录中的word_count.c或 word_count.s文件编译成word_count.o文件

obj-m 表示将Linux驱动作为模块(.ko文件)编译,word_count.o会被连接进word_count.ko文件,然后使用insmod或modprode命令装载word_count.ko

obj-y  表示将Linux驱动编译进Linux内核,word_count.o会被连接进built-in.o 文件,最终会被连接进内核

Linux系统将内存分为了用户空间和内核空间,两者空间的程序不能直接访问,printk函数运行在内核空间,printf函数运行在用户空间,因此属于内核程序的Linux驱动是不能直接访问printf函数的。

#make -C /usr/src/linux-headers-3.0.0-15-generic  M=/root/driver/ch06/word_count    编译Linux驱动源代码

# insmod word_count.ko  装载驱动

# lsmod | grep word_count   查看word_count是否安装成功

# rmmod word_count   卸载Linux驱动

#dmesg | grep word_count | tail -n 2    查看有Linux驱动输出的日志信息

(二)加入有关指定的信息的代码

模块作者:MODULE_AUTHOR("lining");

模块描述:MODULE_DESCRPTION("statistics of word count .");

模块别名:MODULE_ALIAS("word count module.");

开源协议: MODULE_LICENSE("GPL");

#define DEVICE_NAME "wordcount"    //定义设备文件名

//描述与设备文件触发的事件对应的回调函数指针

//owner:设备事件回调幻术应用于哪些驱动模块,THIS_MODULE表示应用于当前驱动模块

static struct file_operations dev_fops={.owner = THIS_MODULE};

//描述设备文件的信息

//minor:次设备号 MISC_DYNAMIC_MINOR,:动态生成次设备号  name :  设备文件名称

//fops : file_operations 结构体变量指针

static struct miscdevice misc={.minor = MISC_DYNAMIC_MINOR, .name=DEVICE_NAME,.fops = &dev_fops};

//初始化Linux驱动

static  int word_count_init(void)

{ int ret;

ret = misc_register(&misc);

printk("word_count_init_success\n");

return ret;

}

// 卸载Linux驱动

static void word_count_exit(void)

{  misc_deregister(&misc);

printk("word_inti_exit_success\n");

}

由于内核空间的程序不能直接访问用户空间中的数据,因此,需要在word_count_read(从设备文件读数据)和word_count_write(向设备文件写数据) 函数中分别使用copy_to_user和copy_from_user函数将数据从内核空间复制到用户空间或从用户空间复制到内核空间

(三)装载与卸载驱动

检查word_count驱动工作是否完全正常

#dmesg | tail -n 1

#modinfo word_count.ko

检测Linux驱动模块的依赖关系

#depmod /root/drivers/ch06/word_count/word_count.ko

调用命令装载Linux驱动

#modprode word_count

注:insmod 和 modprode 命令都是加载驱动,后者可以检查驱动模块的依赖性

三 多种方法测试Linux驱动

(一)使用Ubuntu Linux 测试Linux驱动

需要编写专门用于测试的程序,例如test_word_count.c

#gcc test_word_count.c -o test_word_count

#test_word_count

#test_word_count "I love you."

输出结果: String:I love you.

word byte display:0,0,0,3

word count:3

(二)在android模拟器上通过原生C程序测试Linux驱动

#cd ~/kernel/goldfish

#make menuconfig

     

按照如图所示进行设置,之后重新编译Linux内核,成功编译内核后,android模拟器可以使用性生成的zImage内核文件动态装载Linux驱动模块。

两个条件满足可以直接运行普通的Linux程序:android模拟器、开发板或手机需要有root权限;可执行文件需要使用交叉编译器来编译test_word_count.c文件,建立Android.mk设置编译参数,并使用make命令进行编译

#mm   编译.c文件,在相应目录下

#adb push  ./emulator/test_word_count  /data/local    上传到Android模拟器

执行下面命令测试驱动

#chmod 777 /data/local/test_word_count   设置可执行权限

#/data/local/test_word_count

#/data/local/test_word_count  ‘a bb ccc ddd eee‘

输出结果:5,表示测试成功

(三)使用Android NDK测试

(四)使用开发板测试

(五)将驱动编译进Linux内核进行测试

四 在eclipse中开发Linux驱动程序

第一步:建立C工程

第二步:建立C源代码文件链接     New>Source Folder   Folder name 输入 src,导入word_count.c文件

第三步:设置include路径   单击菜单项properties,C/C++General > Paths and Symbols ,选中Include的GNU C项,Add添加两个路径:/root/kernel/goldfish/include和/root/kernel/goldfish/arch/arm/include

第四步:编译Linux驱动

测试Linux驱动

第一步:导入test_word_count.c文件

第二步:设置include路径

第三步:建立Target      Make Target > Create ,在Target name 文本框中输入word_count_eclipse_test,点击OK

第四步:Build工程    Make Target > Build,选中第三步中建立的文件,然后点击Build

第五步:运行测试程序   Run As > Local C/C++  Application

时间: 2024-08-02 14:15:18

详细讲解Linux驱动程序的相关文章

详细讲解Linux切换用户su指令误区

1.背景 为了安全起见,通常在Linux环境下进行的一般作业建议使用一般账号 这是因为root账号的权限过于庞大,常常会因为不小心的误操作导致系统错误,严重了还会致使系统瘫痪.崩溃. 因此建议只有在需要时才切换到root账号下进行相关操作. su是Linux环境下切换用户的操作指令 2.su指令 很多朋友在使用该指令时,往往使用如下形式: 例:从一般账号moonlit切换到root账号 $ su 那么这么做有什么不对的地方么? 我们这就来观察下账号切换前后的数据对比. [[email prote

关于Linux系统中sed编辑器详细讲解

一.sed简介 sed是非交互式的编辑器.它默认不不编辑源文件,仅仅对模式空间中的数据做处理,并将模式空间中的内容显示在屏幕上.sed编辑器是逐行处理文件,并将结果发送到屏幕.具体过程如下: 首先sed把当前正在处理的行保存在一个临时缓存区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上.sed每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示.处理完输入文件的最后一行后,sed便结束运行.sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会修

第一个linux驱动程序

本章将进行实例的学习,第一个linux驱动程序:统计单词个数.本例子的目的不是讲解如何统计单词个数,而是该算法的实现技术:Linux驱动.Linux系统将每一个驱动都映射成一个文件,这些文件称为设备文件或驱动文件,都保存在/dev目录下.要编写驱动程序还需要更高级的功能,就是linux驱动的事件,就是回调函数. 学习了编写linux驱动程序的步骤.第一步:建立linux驱动骨架:第二步:注册和注销设备文件:第三步:指定与驱动相关的信息:第四步:指定回调函数:第五步:编写业务逻辑:第六步:编写Ma

kettle参数、变量详细讲解

kettle参数.变量详细讲解 kettle 3.2 以前的版本里只有 variable 和 argument,kettle 3.2 中,又引入了 parameter 概念:variable 即environment variables(环境变量或全局变量),即使是不同的转换它们也拥有同样的值:而argument(位置参数)和parameter(命名参数),可以映射为局部变量,只针对一个特定的转换,比如像是限定结果集的大小和过滤条件. 1.     variable(变量) variables

MyBatis Generator 详细讲解

MyBatis Generator中文文档 MyBatis Generator中文文档地址: http://mbg.cndocs.tk/ 该中文文档由于尽可能和原文内容一致,所以有些地方如果不熟悉,看中文版的文档的也会有一定的障碍,所以本章根据该中文文档以及实际应用,使用通俗的语言来讲解详细的配置. 本文中所有节点的链接都是对应的中文文档地址,可以点击查看详细信息. 注:本文后面提到的MBG全部指代MyBatis Generator. 运行MyBatis Generator 有4种运行MBG的方

python编写shell脚本详细讲解

今天需要编写一个shell脚本实现App自动生成的功能,需要处理HTTP REST请求,解析JSON,处理文件,执行命令等,本来想用shell搞定,但感觉比较麻烦,还是用python吧,虽然以前用Python都是在树莓派上玩的,多尝试一种方法总是好的. 虽然我受linux的影响甚深,但是对于*nix 里随处可见的sh脚本却是讨厌之极.为什么讨厌呢?首先是因为sh脚本那莫名其妙的语法,感觉就像随写随扔的程序,完全没有任何美感可言.其次是sh脚本的处理能力还是比较弱的,在文本处理.XML处理还有网络

第一个Linux驱动程序: 统计单词个数

这章主要讲述了一个linux驱动程序,首先说了编写linux驱动程序的步骤 :第 1 步:建立 Linu x 驱动骨架 (装载和卸载 Linu x 驱动)第 2 步:注册和注销设备文件:第 3 步z 指定与驱动相关的信息:第 4 步=指定回调函数 :第 5 步z 编写业务逻辑 :第 6 步:编写 Makefile文件 :第 7 步z 编译 Linux 驱动程序 :第 8 步2 安装和卸载 Linux 驱动:然后就是详细讲了怎样编写 Linux 驱动程序前的准备工作,编写 Linux 驱动程序的骨

Android深度探索(卷1)HAL与驱动开发 第六章 第一个Linux驱动程序:统计单词个数 读书笔记

本章是一个具体的例子,来详细的介绍开发和测试Linux驱动程序的完整过程.尤其是测试Linux驱动.在这个统计单词个数的实例中,重点是该算法的实现技术:即Linux驱动,而不是如何统计的. 6.1Linux驱到底是什么 Linux驱动的工作方式和访问方式是Linux的特点之一.Linux系统将每一个驱动都映射成一个文件,这些文件被称为驱动文件或设备文件,保存在dev目录中.由于大多数Linux驱动都有与其对应的设备文件,因此与Linux驱动交换数据就变成了与设备文件交换数据.事实上,编写Linu

第一个Linux驱动程序统计单词个数

Linux驱动的工作和访问方式是Linux的亮点之一,Linux系统将每一个驱动都映射成一个文件.这些文件称为设备文件或驱动文件,都保存在/dev目录中,这种设计理念使得与Linux驱动进行交互就像与普通文件进行交互一样容易,当然也比访问LinuxAPI更容易. 编写Linux驱动的程序的步骤: 第1步:建立 Linux 驱动骨架(装载和卸载 Linux 驱动) 第2步:注册和注销设备文件 第3步:指定与驱动相关的信息 第4步:指定回调函数 第5步:编写业务逻辑 第6步:编写 Makefile