版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Linux系统驱动概述系统驱动概述驱动程序与应用程序的区别驱动程序与应用程序的区别 n应用程序一般有一个应用程序一般有一个main函数,从头到尾执行一函数,从头到尾执行一个任务;应用程序可以和个任务;应用程序可以和GLIBC库连接库连接n驱动程序没有驱动程序没有main函数,通过使用宏函数,通过使用宏module_init(初始化函数名初始化函数名) 将初始化函数加入内将初始化函数加入内核全局初始化函数列表中,在内核初始化时执行核全局初始化函数列表中,在内核初始化时执行驱动的初始化函数,从而完成驱动的初始化和注驱动的初始化函数,从而完成驱动的初始化和注册,之后驱动便停止等待被应用软件调用。驱动
2、册,之后驱动便停止等待被应用软件调用。驱动程序中有一个宏程序中有一个宏moudule_exit(退出处理函数名退出处理函数名)注册退出处理函数。它在驱动退出时被调用。驱注册退出处理函数。它在驱动退出时被调用。驱动程序中是不能使用标准动程序中是不能使用标准C库的库的 内核版本与编译器的版本依赖内核版本与编译器的版本依赖 n当模块与内核链接时,当模块与内核链接时,insmod会检查模块和当前内核版本会检查模块和当前内核版本是否匹配,每个模块都定义了版本符号是否匹配,每个模块都定义了版本符号_module_kernel _version,这个符号位于模块文件的这个符号位于模块文件的ELF头的头的.m
3、odinfo段中。段中。只要在模块中包含只要在模块中包含,编译器就会自动定义,编译器就会自动定义这个符号这个符号 n每个内核版本都需要特定版本的编译器的支持,高版本的每个内核版本都需要特定版本的编译器的支持,高版本的编译器并不适合低版本的内核,编译器并不适合低版本的内核,Linux-2.4版本的版本的insmod 命命令装载模块时,首先从令装载模块时,首先从/lib/modules目录和内核相关的子目目录和内核相关的子目录中查找模块文件,如果需要从当前目录装载,使用录中查找模块文件,如果需要从当前目录装载,使用insmod module.o。 设备驱动程序的作用设备驱动程序的作用n设备驱动程序
4、将复杂的硬件抽象成一个结构良好的设备,设备驱动程序将复杂的硬件抽象成一个结构良好的设备,并通过提供统一的程序接口为系统的其它部分提供使用并通过提供统一的程序接口为系统的其它部分提供使用设备的能力和方法。设备的能力和方法。n设备驱动程序设备驱动程序(应该只是应该只是)为系统的其它部分提供各种使用为系统的其它部分提供各种使用设备的能力,使用设备的方法应该由应用程序决定。设备的能力,使用设备的方法应该由应用程序决定。nLinux下对外设的访问只能通过驱动程序下对外设的访问只能通过驱动程序nLinux对于驱动程序有统一的接口,以文件的形式定义系对于驱动程序有统一的接口,以文件的形式定义系统的驱动程序:
5、统的驱动程序: Open、Release、read、write、ioctln驱动程序是内核的一部分,可以使用中断、驱动程序是内核的一部分,可以使用中断、DMA等操作等操作n驱动程序需要在用户态和内核态之间传递数据驱动程序需要在用户态和内核态之间传递数据设备驱动程序的分类设备驱动程序的分类n字符设备驱动程序字符设备驱动程序 各种串行接口,并行接口等。各种串行接口,并行接口等。n块设备驱动程序块设备驱动程序 磁盘设备等磁盘设备等n网络设备驱动程序网络设备驱动程序 网卡等。网卡等。n杂项设备驱动程序杂项设备驱动程序 不属于上述三种设备之外的一些设备,如不属于上述三种设备之外的一些设备,如SCSI,时
6、时钟等。钟等。在操作系统中的位置在操作系统中的位置n设备驱动程序是内核代码的一部分。设备驱动程序是内核代码的一部分。n驱动程序的地址空间是内核的地址空间。驱动程序的地址空间是内核的地址空间。n驱动程序的代码直接对设备硬件驱动程序的代码直接对设备硬件(实际是设备的各实际是设备的各种寄存器种寄存器)进行控制进行控制(实际就是读写操作实际就是读写操作)。n应用程序通过操作系统的系统调用执行相应的驱应用程序通过操作系统的系统调用执行相应的驱动程序函数。中断则直接执行相应的中断程序代动程序函数。中断则直接执行相应的中断程序代码。码。n设备驱动程序的设备驱动程序的file_operations结构体的地址
7、被注结构体的地址被注册到内核中的设备链表中。册到内核中的设备链表中。n块设备和字符设备以设备文件的方式建立在文件块设备和字符设备以设备文件的方式建立在文件系统中的系统中的/dev目录下,而且每个设备都有一个主目录下,而且每个设备都有一个主设备号和一个次设备号。设备号和一个次设备号。在操作系统中的位置在操作系统中的位置主设备号和次设备号主设备号和次设备号 n 主设备号相同的设备使用相同的驱动程序,主设备号相同的设备使用相同的驱动程序,次设备号用于区分具体设备的实例。次设备号用于区分具体设备的实例。主设备号标识设备对应的驱动程序主设备号标识设备对应的驱动程序一个驱动程序可以控制若干个设备,次设备号
8、提供了一种一个驱动程序可以控制若干个设备,次设备号提供了一种区分它们的方法区分它们的方法n 系统增加一个驱动程序就要赋予它一个主设系统增加一个驱动程序就要赋予它一个主设备号。这一赋值过程在驱动程序的初始化过备号。这一赋值过程在驱动程序的初始化过程中程中int register_chrdev(unsigned int major, const char*name,struct file_operations *fops);主设备号和次设备号主设备号和次设备号 创建设备节点创建设备节点n设备已经注册到内核表中,对于设备的访问设备已经注册到内核表中,对于设备的访问通过设备文件(设备文件与设备驱动程序
9、的通过设备文件(设备文件与设备驱动程序的主设备号匹配),内核会调用驱动程序中的主设备号匹配),内核会调用驱动程序中的正确函数正确函数n给程序一个它们可以请求设备驱动程序的名给程序一个它们可以请求设备驱动程序的名字。这个名字必须插入到字。这个名字必须插入到/dev目录中,并与目录中,并与驱动程序的主设备号和次设备号相连驱动程序的主设备号和次设备号相连n使用使用mknod在文件系统上创建一个设备节点在文件系统上创建一个设备节点mknod /dev/mydevice c 254 0动态分配设备号动态分配设备号n 在在Documentation/device.txt文件中可以文件中可以找到已经静态分配
10、给大部分设备的列表找到已经静态分配给大部分设备的列表n 由于许多数字已经分配了,为新设备选由于许多数字已经分配了,为新设备选择一个唯一的号码是很困难的择一个唯一的号码是很困难的n 如果调用如果调用register_chrdev时的时的major为零,为零,函数就会选择一个空闲号码并做为返回函数就会选择一个空闲号码并做为返回值返回值返回动态分配的问题动态分配的问题动态分配的主设备号不能保证总是一样的,动态分配的主设备号不能保证总是一样的,无法事先创建设备节点无法事先创建设备节点n 可以从可以从/proc/devices读取读取 cat /proc/devicesn 利用脚本动态创建设备文件节点利
11、用脚本动态创建设备文件节点设备管理的问题设备管理的问题 如今,如今,Linux 支持很多不同种类的硬件。这支持很多不同种类的硬件。这意味着意味着/dev中都有数百个特殊文件来表示所有中都有数百个特殊文件来表示所有这些设备。而且,这些特殊文件中大多数甚至这些设备。而且,这些特殊文件中大多数甚至不会映射到系统中存在的设备上不会映射到系统中存在的设备上使用devfsn 在在Linux 2.4的内核里引入了的内核里引入了devfs来解决来解决linux下设备文件管理的问题下设备文件管理的问题n 在驱动程序中通过在驱动程序中通过devfs_register()函数函数创建设备文件系统的节点创建设备文件系
12、统的节点n 系统启动的时候系统启动的时候mount设备文件系统设备文件系统n 所有需要的设备节点都由内核自动管理。所有需要的设备节点都由内核自动管理。/dev目录下只有挂载的设备目录下只有挂载的设备Linux 2.6内核与内核与devfsnLinux 2.6内核引入了内核引入了sysfs文件系统为每个系统的硬件树进行分级处理文件系统为每个系统的硬件树进行分级处理nDevfs在在Linux 2.6中被标记为舍弃的特性(在中被标记为舍弃的特性(在Linux 2.6.15及以后的版本则及以后的版本则取消了对它的支持取消了对它的支持 ),而使用),而使用udev。 维护动态设备维护动态设备 从从sys
13、fs获得的信息,可以提供对特定设备的固定设备名。对于热插获得的信息,可以提供对特定设备的固定设备名。对于热插拔的设备,这尤其重要拔的设备,这尤其重要 udev 是在用户空间的脚本文件,这很容易被编辑和修改是在用户空间的脚本文件,这很容易被编辑和修改 可以和可以和hotplug脚本配合使用脚本配合使用n为了保证旧应用程序的兼容性,在嵌入式系统中,用为了保证旧应用程序的兼容性,在嵌入式系统中,用devfs还是一个好方还是一个好方法。即使在法。即使在Linux 2.6.15内核以后,也可以通过内核以后,也可以通过ndevfs(nano devfs)补丁)补丁提供对提供对devfs特性的兼容。特性的兼
14、容。在在Linux 2.6内核中使用内核中使用udevn 建议,在建议,在2.6.15以后的版本中使用以后的版本中使用udevn 使用使用ramfs作为作为udev的载体的载体 mount t ramfs none /devn udev使用的规则集位于使用的规则集位于/etc/udev/*n udev的官方地址:的官方地址:/pub/linux/utils/kernel/hotplug/udev.html设备驱动程序的使用方法设备驱动程序的使用方法n 应用层使用open、close、read、write系统调用需要编写应用程序n 使用系统命令可以进行最基
15、本的测试: cat /dev/urandom echo /dev/urandom /dev/fb0 dd if=/dev/touchscreen of=/var/tmp/test bs=16 count=100Linux设备驱动程序结构设备驱动程序结构n 结构体file_operations的定义,在include/linux/fs.h中n 主要包括:open,close(或者release),read,write,ioctl,poll,mmap等 简单的简单的Linux驱动程序原理驱动程序原理Linux设备驱动程序结构的例子(设备驱动程序结构的例子(1)Linux设备驱动程序结构的例子设备驱
16、动程序结构的例子(2)/* 驱动程序中使用的各种函数的原型声明。标准的作法是将函数原型声明* 放在一个头文件中,然后在该文件开始处使用#include引用,并在该*文件中定义。*这里我们将函数的声明和定义放在一起。所以下面的代码既是函数的声明,* 也是函数的定义。*/static ssize_t demo_read(structfile *filp, char *buffsize_tcnt, loof_t*off)/* 这里是这里是read函数的代码函数的代码* /return ret;static ssize_t demo_write(structfile *filp, char *buff
17、size_tcnt, loff_t*off)/* 这里是这里是write函数的代码函数的代码*/return ret;Linux设备驱动程序结构的例子设备驱动程序结构的例子(3)static int demo_ioctl(structinode*inode, structfile *filpunsigned intcmd, unsigned long arg)/* 这里是这里是ioctl函数的代码,它的一般格式为一个函数的代码,它的一般格式为一个switch分支语句分支语句*switch(cmd) *case CMD1: *.*break;*.*case CMDn:*.*break*defau
18、lt:*.*break;*/return ret; ioctl()函数用于控制驱动程序本身的一些特性和参数,如设定驱动函数用于控制驱动程序本身的一些特性和参数,如设定驱动程序使用的缓冲区的大小,设定串行通讯的速率等。程序使用的缓冲区的大小,设定串行通讯的速率等。Linux设备驱动程序结构的例子设备驱动程序结构的例子(4)static int demo_open(structinode*inode, structfile *filp)/* 这里是这里是open函数的代码函数的代码*/return ret;static int demo_close(structinode*inode, struc
19、tfile *filp)/* 这里是这里是close函数的代码函数的代码*/return ret; 上述上述5个函数,既个函数,既read(), write(), ioctl(), open(), close(),是一个字符设备,是一个字符设备驱动程序最基本的需要由驱动程序的作者完成的函数。这驱动程序最基本的需要由驱动程序的作者完成的函数。这5个函数将对个函数将对应于相应的应于相应的5个系统调用:个系统调用:read() - demo_read()write() - demo_write()ioctl() - demo_ioctl ()open() - demo_open()close() -
20、 demo_close()系统调用驱动程序函数Linux设备驱动程序结构的例子设备驱动程序结构的例子(5)static struct file_operations demo_fops= read: demo_read,write: demo_write,ioctl: demo_ioctl,open: demo_open,release: demo_close,;file_operations是一个结构体类型,定义在include/linux/fs.h中。上述代码定义了一个file_operations类型的结构体demo_fops,并将其中的一些成员赋了初值。结构体demo_fops将作为一
21、个参数在注册一个设备驱动程序时传递给内核。内核使用设备链表维护各种注册的设备。不同类型的设备使用不同的链表。Linux设备驱动程序结构的例子设备驱动程序结构的例子(6)static int_init demo_init(void)/* 设备初始化代码等*/if(register_chrdev(DEMO_MAJOR, “demo”, &spioc_fops) printk(KERN_ERR“demo.c: unable to register ”“the device with major %d.n”, DEMO_MAJOR);return EIO;/* 其他初始化代码*/return
22、ret;static void _exit demo_exit(void)/* 设备撤消代码*/if(unregister_chrdev(DEMO_MAJOR, “demo”) Printk(ERN_ERR“demo.c: unable to remove the ” “device with major %d.n”, DEMO_MAJOR);return;/* 其它设备撤消代码*/return;Linux设备驱动程序结构的例子设备驱动程序结构的例子(7)module_init(demo_init);module_exit(demo_exit);这两个函数,module_init()和modu
23、le_exit(),用于告诉内核,当一个驱动程序加载和退出(或撤消)时,需要执行的操作。不同驱动程序在加载和退出时,除了基本的向内核注册设备驱动程序外,还有各自的针对具体设备的操作。Linux设备驱动程序结构的例子设备驱动程序结构的例子(8)要点总结要点总结:宏:_KERNEL_, MODULE, _VERSION_KERNEL_:表明这将是用于内核的代码,否则很多内核过程将无法使用。MODULE:如果是以模块方式编译,需要定义这个宏;如果是静态连接则不用。_VERSION_:定义这个宏则需要驱动程序的内核版本要和内核版本一致。module_init()/module_exit(): demo
24、_init()/demo_exit()每个驱动程序都要有这两个函数,它们分别用于设备驱动程序的加载和撤消。static struct file_operations demo_fops:每个驱动程序都要有这样的结构体,可能不止一个。用register_chrdev()注册驱动程序时这个结构体的起始地址被传送到内核的设备表中。DEMO_MAJOR:每个设备驱动程序有一个主设备号(major number)。不同设备驱动程序不能使用相同的主设备号。一个设备驱动程序可以管理不同的(但一般是同一类的)设备,通过次设备号(minor number)区分。demo_ open()/close(),read
25、()/write(), ioctl():根据具体驱动程序定义和使用。一般open()/close()总是需要的,而且open()和close()一定要成对出现。设备驱动程序的使用设备驱动程序的使用n 驱动程序模块的动态链接和静态链接驱动程序模块的动态链接和静态链接n 创建设备文件创建设备文件n 使用设备使用设备驱动程序模块的加载驱动程序模块的加载n 设备驱动程序被静态编译到内核中的情况设备驱动程序被静态编译到内核中的情况:module_init()指示内核在启动过程中运行设备的初始化函数,如指示内核在启动过程中运行设备的初始化函数,如demo_init()函数。驱动程序的加载随内核的启动一起完
26、成。函数。驱动程序的加载随内核的启动一起完成。静态编译的内核模块不能被动态卸载,只有到系统关闭时由内核执行相应的静态编译的内核模块不能被动态卸载,只有到系统关闭时由内核执行相应的卸载函数,如卸载函数,如demo_exit()。嵌入式操作系统一般使用静态内核模块以减少系统的尺寸和复杂性。嵌入式操作系统一般使用静态内核模块以减少系统的尺寸和复杂性。n 设备驱动程序被动态加载到内核中的情况设备驱动程序被动态加载到内核中的情况:首先,驱动程序需要被编译成目标文件,如首先,驱动程序需要被编译成目标文件,如demo.o。在操作系统运行之后,使用在操作系统运行之后,使用insmod命令将驱动程序模块动态加载到内核中命令将驱动程序模块动态加载到内核中$ insmod demo.o使用使用insmod命令动态加载的内核模块可以使用命令动态加载的内核模块可以使用rmmod命令动态地从内核
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 妊娠期免疫抑制剂治疗窗管理策略
- 妊娠期代谢异常的营养-内分泌管理策略
- 妊娠合并地贫的产前基因诊断策略
- 鞍山美术考试题目及答案
- 大数据支持下社区慢病防控的精准化路径
- 医学考试大题题库及答案
- 2025年中职(调味品生产技术)调味品制作阶段测试题及答案
- 2025年大学建筑工程施工(钢筋绑扎工艺)试题及答案
- 2025年中职(新能源汽车技术)新能源汽车概论试题及答案
- 2025年中职电子电器应用与维修(电子电器应用)试题及答案
- 心房钠尿肽基因敲除小鼠的繁殖和鉴定
- 母婴护理职业道德课件
- 广元市利州区何家坪石材厂饰面用灰岩矿矿山地质环境保护与土地复垦方案
- 医疗废物处理方案
- 船舶靠离泊作业风险辨识表
- 口腔颌面外科学(全)
- 安徽金轩科技有限公司 年产60万吨硫磺制酸项目环境影响报告书
- 魔鬼理论之k线秘笈图解课件
- 2023届广东省佛山市普通高中高三上学期教学质量检测(一模)物理试题含答案
- GB/T 9163-2001关节轴承向心关节轴承
- GB/T 36342-2018智慧校园总体框架
评论
0/150
提交评论