Linux系统驱动概述.ppt_第1页
Linux系统驱动概述.ppt_第2页
Linux系统驱动概述.ppt_第3页
Linux系统驱动概述.ppt_第4页
Linux系统驱动概述.ppt_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux系统驱动概述 驱动程序与应用程序的区别 n 应用程序一般有一个main函数,从头到尾执行一 个任务;应用程序可以和GLIBC库连接 n 驱动程序没有main函数,通过使用宏 module_init(初始化函数名) 将初始化函数加入内 核全局初始化函数列表中,在内核初始化时执行 驱动的初始化函数,从而完成驱动的初始化和注 册,之后驱动便停止等待被应用软件调用。驱动 程序中有一个宏moudule_exit(退出处理函数名)注 册退出处理函数。它在驱动退出时被调用。驱动 程序中是不能使用标准C库的 内核版本与编译器的版本依赖 n 当模块与内核链接时,insmod会检查模块和当前内核版本 是否匹配,每个模块都定义了版本符号_module_kernel _version,这个符号位于模块文件的ELF头的.modinfo段中。 只要在模块中包含,编译器就会自动定义 这个符号 n 每个内核版本都需要特定版本的编译器的支持,高版本的 编译器并不适合低版本的内核,Linux-2.4版本的insmod 命 令装载模块时,首先从/lib/modules目录和内核相关的子目 录中查找模块文件,如果需要从当前目录装载,使用 insmod module.o。 设备驱动程序的作用 n 设备驱动程序将复杂的硬件抽象成一个结构良好的设备 ,并通过提供统一的程序接口为系统的其它部分提供使 用设备的能力和方法。 n 设备驱动程序(应该只是)为系统的其它部分提供各种使用 设备的能力,使用设备的方法应该由应用程序决定。 n Linux下对外设的访问只能通过驱动程序 n Linux对于驱动程序有统一的接口,以文件的形式定义系 统的驱动程序: Open、Release、read、write、ioctl n 驱动程序是内核的一部分,可以使用中断、DMA等操作 n 驱动程序需要在用户态和内核态之间传递数据 设备驱动程序的分类 n 字符设备驱动程序 各种串行接口,并行接口等。 n 块设备驱动程序 磁盘设备等 n 网络设备驱动程序 网卡等。 n 杂项设备驱动程序 不属于上述三种设备之外的一些设备,如SCSI, 时钟等。 在操作系统中的位置 n 设备驱动程序是内核代码的一部分。 n 驱动程序的地址空间是内核的地址空间。 n 驱动程序的代码直接对设备硬件(实际是设备的各 种寄存器)进行控制(实际就是读写操作)。 n 应用程序通过操作系统的系统调用执行相应的驱 动程序函数。中断则直接执行相应的中断程序代 码。 n 设备驱动程序的file_operations结构体的地址被注 册到内核中的设备链表中。 n 块设备和字符设备以设备文件的方式建立在文件 系统中的/dev目录下,而且每个设备都有一个主 设备号和一个次设备号。 在操作系统中的位置 主设备号和次设备号 n主设备号相同的设备使用相同的驱动程序, 次设备号用于区分具体设备的实例。 主设备号标识设备对应的驱动程序 一个驱动程序可以控制若干个设备,次设备号提供了一种 区分它们的方法 n系统增加一个驱动程序就要赋予它一个主设 备号。这一赋值过程在驱动程序的初始化过 程中 int register_chrdev(unsigned int major, const char*name,struct file_operations *fops); 主设备号和次设备号 创建设备节点 n 设备已经注册到内核表中,对于设备的访问 通过设备文件(设备文件与设备驱动程序的 主设备号匹配),内核会调用驱动程序中的 正确函数 n 给程序一个它们可以请求设备驱动程序的名 字。这个名字必须插入到/dev目录中,并与驱 动程序的主设备号和次设备号相连 n 使用mknod在文件系统上创建一个设备节点 mknod /dev/mydevice c 254 0 动态分配设备号 n在Documentation/device.txt文件中可以 找到已经静态分配给大部分设备的列表 n由于许多数字已经分配了,为新设备选 择一个唯一的号码是很困难的 n如果调用register_chrdev时的major为零 ,函数就会选择一个空闲号码并做为返 回值返回 动态分配的问题 动态分配的主设备号不能保证总是一样的 ,无法事先创建设备节点 n可以从/proc/devices读取 cat /proc/devices n利用脚本动态创建设备文件节点 设备管理的问题 如今,Linux 支持很多不同种类的硬件。这 意味着/dev中都有数百个特殊文件来表示所有 这些设备。而且,这些特殊文件中大多数甚至 不会映射到系统中存在的设备上 使用devfs n在Linux 2.4的内核里引入了devfs来解 决 linux下设备文件管理的问题 n在驱动程序中通过devfs_register()函数 创建设备文件系统的节点 n系统启动的时候mount设备文件系统 n所有需要的设备节点都由内核自动管理 。 /dev目录下只有挂载的设备 Linux 2.6内核与devfs nLinux 2.6内核引入了sysfs文件系统为每个系统的硬件树进行分级处理 nDevfs在Linux 2.6中被标记为舍弃的特性(在Linux 2.6.15及以后的版本则 取消了对它的支持 ),而使用udev。 维护动态设备 从sysfs获得的信息,可以提供对特定设备的固定设备名。对于热插拔 的设备,这尤其重要 udev 是在用户空间的脚本文件,这很容易被编辑和修改 可以和hotplug脚本配合使用 n为了保证旧应用程序的兼容性,在嵌入式系统中,用devfs还是一个好方 法。即使在Linux 2.6.15内核以后,也可以通过ndevfs(nano devfs)补丁 提供对devfs特性的兼容。 在Linux 2.6内核中使用udev n建议,在2.6.15以后的版本中使用udev n使用ramfs作为udev的载体 mount t ramfs none /dev nudev使用的规则集位于/etc/udev/* nudev的官方地址: /pub/linux/utils/kerne l/hotplug/udev.html 设备驱动程序的使用方法 n应用层使用open、close、read、write系 统调用需要编写应用程序 n使用系统命令可以进行最基本的测试: cat /dev/urandom echo /dev/urandom /dev/fb0 dd if=/dev/touchscreen of=/var/tmp/test bs=16 count=100 Linux设备驱动程序结构 n结构体file_operations的定义,在 include/linux/fs.h中 n主要包括:open,close(或者release), read,write,ioctl,poll,mmap等 简单的Linux驱动程序原理 Linux设备驱动程序结构的例子(1 ) Linux设备驱动程序结构的例子 (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 *buffsize_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 *default: *. *break; * */ return ret; ioctl()函数用于控制驱动程序本身的一些特性和参数,如设定驱动 程序使用的缓冲区的大小,设定串行通讯的速率等。 Linux设备驱动程序结构的例子 (4) static int demo_open(structinode*inode, structfile *filp) /* 这里是open函数的代码*/ return ret; static int demo_close(structinode*inode, structfile *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() - 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将作为一个参数在注册一个设备驱动程序时传递给内核 。内核使用设备链表维护各种注册的设备。不同类型的设备使用不同的 链表。 Linux设备驱动程序结构的例子 (6) static int_init demo_init(void) /* 设备初始化代码等*/ if(register_chrdev(DEMO_MAJOR, “demo”, return EIO; /* 其他初始化代码*/ return 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()和module_exit(),用于告诉内核,当 一个驱动程序加载和退出(或撤消)时,需要执行的操作。不 同驱动程序在加载和退出时,除了基本的向内核注册设备驱动 程序外,还有各自的针对具体设备的操作。 Linux设备驱动程序结构的例子 (8) 要点总结: 宏:_KERNEL_, MODULE, _VERSION_ _KERNEL_:表明这将是用于内核的代码,否则很多内核过程将无法使用。 MODULE:如果是以模块方式编译,需要定义这个宏;如果是静态连接则不用 。 _VERSION_:定义这个宏则需要驱动程序的内核版本要和内核版本一致。 module_init()/module_exit(): demo_init()/demo_exit() 每个驱动程序都要有这两个函数,它们分别用于设备驱动程序的加载和撤消。 static struct file_operations demo_fops: 每个驱动程序都要有这样的结构体,可能不止一个。用register_chrdev() 注册驱动程序时这个结构体的起始地址被传送到内核的设备表中。 DEMO_MAJOR: 每个设备驱动程序有一个主设备号(major number)。不同设备驱动程序不能 使用相同的主设备号。一个设备驱动程序可以管理不同的(但一般是同一类的) 设备,通过次设备号(minor number)区分。 demo_ open()/close(),read()/write(), ioctl(): 根据具体驱动程序定义和使用。一般open()/close()总是需要的,而且 open()和close()一定要成对出现。 设备驱动程序的使用 n 驱动程序模块的动态链接和静态链接 n 创建设备文件 n 使用设备 驱动程序模块的加载 n 设备驱动程序被静态编译到内核中的情况: module_init()指示内核在启动过程中运行设备的初始化函数,如demo_init()函 数。驱动程序的加载随内核的启动一起完成。 静态编译的内核模块不能被动态卸载,只有到系统关闭时由内核执行相应的卸 载函数,如demo_exit()。 嵌入式操作系统一般使用静态内核模块以减少系统的尺寸和复杂性。 n 设备驱动程序被动态加载到内核中的情

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论