嵌入式学院第期Linux字符设备驱动.ppt
《嵌入式学院第期Linux字符设备驱动.ppt》由会员分享,可在线阅读,更多相关《嵌入式学院第期Linux字符设备驱动.ppt(187页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、嵌入式学院第期Linux字符设备驱动 Still waters run deep.流静水深流静水深,人静心深人静心深 Where there is life,there is hope。有生命必有希望。有生命必有希望2版权华华清清远见远见嵌入式培嵌入式培训训中心版中心版权权所有;所有;未未经华经华清清远见远见明确明确许许可,不能可,不能为为任何目的以任何形式复制任何目的以任何形式复制或或传传播此文档的任何部分;播此文档的任何部分;本文档包含的信息如有更改,恕不另行通知;本文档包含的信息如有更改,恕不另行通知;保留所有保留所有权权利。利。www.embedu.org Linux驱动程序基础知识
2、LinuxLinux字符设备驱动基础字符设备驱动基础 三种重要数据结构及关系三种重要数据结构及关系 file_oprationsfile_oprations结构分析结构分析 用户空间与内核空间数据传输用户空间与内核空间数据传输基本字符设备驱动函数模板www.embedu.org设备驱动程序基础Linux设备驱动概念驱动程序为操作硬件提供良好内部接口驱动程序为应用程序提供了访问设备的机制Linux设备驱动分类字符设备:键盘、鼠标、串口块设备:硬盘、Flash 网络接口:以太网特定类型设备:audio设备www.embedu.orgLinux内核功能的划分www.embedu.org系统调用和设备
3、I/O www.embedu.org驱动程序的两大任务作为系统调用的一部分而执行,运行在进程上下文。负责中断处理,运行在中断上下文www.embedu.org设备驱动健壮性和安全性机制和策略的折衷驱动程序是内核的一部分驱动程序的漏洞和缺陷直接危及内核留心未初始化的指针,恶意用户程序,缓冲区溢出www.embedu.org驱动程序与内核版本号Linux内核版本号简述 2.0.x 2.2.x 2.4.x 2.6.x版本号在内核编译过程中的影响模块加载时的版本号检查www.embedu.orgLinux下构建和运行模块为什么用模块?模块和应用程序有什么不同#ifdef _KERNEL_#ifdef
4、MODULEwww.embedu.orgLinux驱动程序模块加载 2.4内核:www.embedu.orgLinux驱动程序模块加载2.6内核:www.embedu.org模块的版本依赖版本号定义可以区分不同版本内核的接口函数可以在linux/version.h找到版本定义KERNEL_VERSIONwww.embedu.org模块初始化和关闭模块加载调用的第一个函数init_module模块所使用资源的分配与释放使用计数模块卸载和cleanup_module显式指定初始化和清除函数www.embedu.org一个简单的Linux内核模块 1#include 2#include 3 MODU
5、LE_LICENSE(Dual BSD/GPL);4 static int hello_init(void)5 6 printk(KERN_ALERT Hello World entern);7 return 0;8 9 static void hello_exit(void)10 11 printk(KERN_ALERT Hello World exitn);12 13 module_init(hello_init);14 module_exit(hello_exit);15 16 MODULE_AUTHOR(Song Baohua);17 MODULE_DESCRIPTION(A simp
6、le Hello World Module);18 MODULE_ALIAS(a simplest module);www.embedu.orgLinux内核模块的程序结构 模块加载函数(必须)模块卸载函数(必须)模块许可证声明(必须)大多数情况下,内核模块应遵循GPL兼容许可权。Linux 2.6内核模块最常见的是以MODULE_LICENSE(Dual BSD/GPL)语句声明模块采用BSD/GPL双LICENSE。模块参数(可选)。模块导出符号(可选)模块作者等信息声明(可选)www.embedu.org模块参数 module_param(参数名,参数类型,参数读/写权限)module_
7、param(myshort,short,0000);MODULE_PARM_DESC(myshort,A short integer);module_param(myint,int,0000);MODULE_PARM_DESC(myint,An integer);#insmod hello.ko myshort=55 myint=456www.embedu.org导出符号 Linux 2.6的“/proc/kallsyms”文件对应着内核符号表,它记录了符号以及符号所在的内存地址。模块可以使用如下宏导出符号到内核符号表:EXPORT_SYMBOL(符号名);EXPORT_SYMBOL_GPL(
8、符号名);www.embedu.org模块的使用计数 Linux 2.4内核:MOD_INC_USE_COUNT、MOD_DEC_USE_COUNT Linux 2.6内核:try_module_get(&module)该函数用于增加模块使用计数 module_put(&module)该函数用于减少模块使用计数 www.embedu.orgLinux内核与模块中的并发可重入简介共享资源带来的问题并发与竞态抢占式内核对并发的影响www.embedu.org产生并发的三种情况对称多处理器(SMP)多个CPUwww.embedu.org产生并发的三种情况单CPU内进程与抢占它的进程中断与进程之间ww
9、w.embedu.org解决并发的途径互斥访问临界区(critical section)www.embedu.org模块的编译和装载编译模块都需要什么编译模块相关的宏模块工具insmod,rmmod,lsmod,modprobe,modinfowww.embedu.org Linux驱动程序基础知识 LinuxLinux字符设备驱动基础字符设备驱动基础 三种重要数据结构及关系三种重要数据结构及关系 file_oprationsfile_oprations结构分析结构分析 用户空间与内核空间数据传输用户空间与内核空间数据传输基本字符设备驱动函数模板www.embedu.orgLinux字符设备驱
10、动基础驱动注册与初始化主设备号和次设备号设备名设备文件节点操作与file operation结构用户系统调用与驱动函数集合www.embedu.org设备名与主次设备号字符设备文件例子crw-rw-1 root uucp 4,64 2005-03-20 03:36/dev/ttyS0主设备号区分设备驱动程序次设备号区分同一个驱动程序创建的多个设备常见于多个串口,硬盘分区等mknod 创建设备文件:mknod /dev/mydevice c 254 0open、close等操作/dev/下设备文件,内核根据文件的主设备号找到对应驱动程序主设备号可以分为动态、静态申请www.embedu.org动
11、态分配主设备号alloc_chrdev_region注册动态主设备号(2.6)动态分配主设备号的优缺点/proc/devices和lsmod动态生成设备文件系统节点dev_t和kdev_twww.embedu.orgfile_opration结构分析file 在内核中定义linux/fs.hfile struct Mode_t f_modeLoff_t f_posUnsigned int f_flagsStruct file_operations*f_opvoid*private_dataStruct dentry*f_dentrywww.embedu.org Linux驱动程序基础知识 Li
12、nuxLinux字符设备驱动基础字符设备驱动基础 三种重要数据结构及关系三种重要数据结构及关系 file_oprationsfile_oprations结构分析结构分析 用户空间与内核空间数据传输用户空间与内核空间数据传输基本字符设备驱动函数模板www.embedu.org三种重要数据结构及关系include/linux/fs.hstruct file_operations struct module*owner;loff_t(*llseek)(struct file*,loff_t,int);ssize_t(*read)(struct file*,char _user*,size_t,lof
13、f_t*);ssize_t(*write)(struct file*,const char _user*,size_t,loff_t*);unsigned int(*poll)(struct file*,struct poll_table_struct*);int(*ioctl)(struct inode*,struct file*,unsigned int,unsigned long);int(*mmap)(struct file*,struct vm_area_struct*);int(*open)(struct inode*,struct file*);int(*release)(str
14、uct inode*,struct file*);定义了针对文件的一系列操作方法定义了针对文件的一系列操作方法www.embedu.org三种重要数据结构及关系include/linux/fsstruct file mode_t f_mode;loff_t f_ops;unsigned int f_flags;struct file_operations *f_op;void *private_data;struct dentry *f_dentry;系统中每个打开的文件在内核空间都有一个对应的系统中每个打开的文件在内核空间都有一个对应的file结构结构www.embedu.org三种重要数据
15、结构及关系include/linux/fs.hstruct inode dev_t i_rdev;/包含真正的设备编号struct cdev *i_cdev;/指向cdev结构的指针;inode结构体用于描述文件的静态属性结构体用于描述文件的静态属性,每个文件对应一个每个文件对应一个唯一的唯一的inode结构结构www.embedu.orgfile_opration结构分析file_operations 在内核中定义linux/fs.h struct file_operations struct module*owner;loff_t(*llseek)(struct file*,loff_t,
16、int);ssize_t(*read)(struct file*,char _user*,size_t,loff_t*);ssize_t(*write)(struct file*,const char _user*,size_t,loff_t*);unsigned int(*poll)(struct file*,struct poll_table_struct*);int(*ioctl)(struct inode*,struct file*,unsigned int,unsigned long);int(*mmap)(struct file*,struct vm_area_struct*);i
17、nt(*open)(struct inode*,struct file*);int(*release)(struct inode*,struct file*);int(*fsync)(struct file*,struct dentry*,int datasync);www.embedu.orgfile_operationsint(*open)(struct inode*,struct file*)增加使用计数,检查错误如果未初始化,则调用初始化识别次设备号,如果必要,更新f_op指针分配并填写被置于filp-private_data的数据结构int(*realse)(struct inode
18、*,struct file*)open逆操作www.embedu.orgfile_operationsssize_t(*read)(struct file*,char*,size_t,loff_t*)用户空间和内核空间数据交互用户空间指针和内核指针驱动调用copy_to_user()将数据返回给用户ssize_t(*write)(struct file*,const char*,size_t,loff_t*)驱动调用copy_from_user()将用户数据读到本地bufferwww.embedu.orgfile_operationsint(*mmap)(struct file*,struct
19、 vm_area_struct*)驱动中提供该方法用于支持用户mmap操作用户将设备内存区映射到进程的地址空间,直接操作该物理内存提高效率典型例子:framebuffer,sound,capture等驱动www.embedu.orgfile_operationsint(*ioctl)(struct inode*,struct file*,unsigned int cmd,unsigned long arg)驱动程序一般需支持通过Ioctl实现各种控制与参数设置,如串口可设置波特率等多参数cmd变量存放命令,驱动代码根据cmd里面的值进行switch-case处理分支arg存放参数,如为整数,可
20、直接使用。如为指针,驱动程序首先要检查指针的合法性int access_ok(int type,const void*addr,unsigned long size);检查通过后可以使用驱动程序还可通过int capable(int capability)函数来确定调用进程是否有权执行操作www.embedu.org怎样使用ioctl用户系统调用:int ioctl(int fd,int cmd,.);cmd命令码格式用户空间与Linux内核中定义需一致:_|设备类型|序列号|方向|数据尺寸|-|-|-|-|8 bit|8 bit|2 bit|814 bit|www.embedu.orgIoc
21、tl权能和受限操作驱动程序的访问控制采用linux文件系统的权限机制驱动程序采用权能机制来控制特殊的操作权限驱动程序通过int capable(int capability);函数来确定调用进程是否有权执行操作www.embedu.org用ioctl控制驱动程序实例分析int scull_ioctl(struct inode*inode,struct file*filp,unsigned int cmd,unsigned long arg)int err=0,tmp;int retval=0;if(_IOC_TYPE(cmd)!=SCULL_IOC_MAGIC)return-ENOTTY;if
22、(_IOC_NR(cmd)SCULL_IOC_MAXNR)return-ENOTTY;if(_IOC_DIR(cmd)&_IOC_READ)err=!access_ok(VERIFY_WRITE,(void _user*)arg,_IOC_SIZE(cmd);else if(_IOC_DIR(cmd)&_IOC_WRITE)err=!access_ok(VERIFY_READ,(void _user*)arg,_IOC_SIZE(cmd);if(err)return-EFAULT;www.embedu.org用ioctl控制驱动程序实例分析switch(cmd)case SCULL_IOCRE
23、SET:scull_quantum=SCULL_QUANTUM;scull_qset=SCULL_QSET;break;case SCULL_IOCSQUANTUM:/*Set:arg points to the value*/if(!capable(CAP_SYS_ADMIN)return-EPERM;retval=_get_user(scull_quantum,(int _user*)arg);break;case SCULL_IOCTQUANTUM:/*Tell:arg is the value*/if(!capable(CAP_SYS_ADMIN)return-EPERM;scull_
24、quantum=arg;break;case SCULL_IOCGQUANTUM:/*Get:arg is pointer to result*/retval=_put_user(scull_quantum,(int _user*)arg);break;www.embedu.org Linux驱动程序基础知识 LinuxLinux字符设备驱动基础字符设备驱动基础 三种重要数据结构及关系三种重要数据结构及关系 file_oprationsfile_oprations结构分析结构分析 用户空间与内核空间数据传输用户空间与内核空间数据传输基本字符设备驱动函数模板www.embedu.org用户空间与
25、内核空间数据传输用户(进程)空间受保护的空间,执行于“用户模式”所有地址都是“逻辑”的,不能访问不属于自己的内存需要转换成物理的(真实的)地址执行指令时由硬件辅助完成转换发生页面错误时间接地由操作系统完成内核(系统)空间不受保护的空间,执行于“超级模式”能访问任何内存,所有地址都是“逻辑”的需要转换成物理的(真实的)地址执行指令时由硬件辅助完成转换发生页面错误时,间接地由操作系统完成www.embedu.org驱动程序使用的内存获取内存区(kmalloc分配物理内存)BufferDMA bufferioport和iomem映射及使用用户静态映射(iodesc,iomap)动态映射(iorema
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 学院 Linux 字符 设备 驱动
限制150内