ImageVerifierCode 换一换
格式:DOCX , 页数:24 ,大小:166.60KB ,
资源ID:8971838      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/8971838.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(linux内核驱动模块编写ioctl.docx)为本站上传会员【xrp****65】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

linux内核驱动模块编写ioctl.docx

1、如果你对内核驱动模块一无所知,请先学习内核驱动模块的基础知识。 如果你已经入门了内核驱动模块,但是仍感觉有些模糊,不能从整体来了解一个内核驱动模块的结构,请赏读一下这篇拙文。 如果你已经从事内核模块编程N年,并且道行高深,也请不吝赐教一下文中的疏漏错误。   本文中我将实现一个简单的Linux字符设备,旨在大致勾勒出linux内核模块的编写方法的轮廓。其中重点介绍ioctl的用途。 我把这个简单的Linux字符设备模块命名为hello_mod. 设备类型名为hello_class 设备名为hello   该设备是一个虚拟设备,模块加载时会在/sys/class/中创建名为he

2、llo_class的逻辑设备,在/dev/中创建hello的物理设备文件。模块名为hello_mod,可接受输入字符串数据(长度小于128),处理该输入字符串之后可向外输出字符串。并且可以接受ioctl()函数控制内部处理字符串的方式。 例如: a.通过write函数写入 “Tom”,通过ioctl函数设置langtype=chinese,通过read函数读出的数据将会是“你好!Tom/n” b.通过write函数写入 “Tom”,通过ioctl函数设置langtype=english,通过read函数读出的数据将会是“hello!Tom/n” c.通过write函数写入 “Tom”,

3、通过ioctl函数设置langtype=pinyin,通过read函数读出的数据将会是“ni hao!Tom/n”     一般的内核模块中不会负责设备类别和节点的创建,我们在编译完之后会得到.o或者.ko文件,然后insmod之后需要mknod来创建相应文件,这个简单的例子中我们让驱动模块加载时负责自动创建设备类别和设备文件。这个功能有两个步骤, 1)创建设备类别文件  class_create(); 2)创建设备文件   device_create(); 关于这两个函数的使用方法请参阅其他资料。   linux设备驱动的编写相对windows编程来说更容易理解一点因为不需要

4、处理IRP,应用层函数和内核函数的关联方式浅显易懂。 比如当应曾函数对我的设备调用了open()函数,而最终这个应用层函数会调用我的设备中的自定义open()函数,这个函数要怎么写呢, 我在我的设备中定义的函数名是hello_mod_open,注意函数名是可以随意定义,但是函数签名是要符合内核要求的,具体的定义是怎么样请看   static int hello_mod_open(struct inode *, struct file *);   这样就定义了内核中的open函数,这只是定义还需要与我们自己的模块关联起来,这就要用到一个结构   struc

5、t file_operations   这个结构里面的成员是对应于设备操作的各种函数的指针。 我在设备中用到了这些函数所以就如下定义,注意下面的写法不是标准ANSI C的语法,而是GNU扩展语法。   struct file_operations hello_mod_fops = {  .owner = THIS_MODULE,  .open = hello_mod_open,  .read = hello_mod_read,  .write = hello_mod_write,  .ioctl = hello_mod_ioctl,  .release = hello

6、mod_release, };   这个结构体变量定义好之后我们在模块初始化函数中就可以通过register_chrdev()或者填充cdev结构来关联所有的操作到我们的模块函数了。   和设备交互的数据我们总称为“数据”,但是大致可划分为两种 “功能数据”:我们要输入设备处理的和设备处理完之后输出的数据。 “控制数据”:我们用来控制设备特性功能的命令和参数。 open,read,write,release等函数是对一个驱动模块的使用,就是我们对“设备的功能”的使用。但是一个设备有可能有很多功能,那么我们要怎么控制设备让设备完成指定的功能呢? 据个例子来说:假如我们有一个翻

7、译机(姑且说机吧,也可能是器)实体设备,主要功能是输入中文,然后可以输出各种语言对应的翻译结果,那这个机的功能就是翻译,我们真正用来处理的数据是我们输入的中文,我们要得到的“设备功能”就是翻译后的输出内容,而各种语言则是我们的选择控制了,我们可设定这个设备翻译成何种语言。这就要求我们要向设备发送命令,设定目标语言。请注意我们要发送的是两个“控制数据”,命令和参数。   命令:一个设备可能有很多种行为,我们的命令就是代表我们要让设备执行何种行为。“复位”,“设定目标语言”,“获得当前目标语言”等 参数:对于某一个命令,可能需要参数可能不需要参数。         比如:        

8、 “复位”命令就不需要参数。         “设定目标语言”则需要传入目标语言的类型。         “获取目标语言”则需要传入一个能够接收目标语言类型的参数。   自己画了一个设备“数据流”图,希望能加深理解。   对于我们自己的设备我们就要自己定义设备命令了,如果你要想搞清命令的格式,请参考其他资料关于ioctl的参数的介绍。 这里不打算介绍这个,只介绍ioctl实际功能。定义自己的IO控制命令需要用到宏。这里直接写出我的定义而不是介绍宏的实现   #define HELLO_MAGIC 12 #define HELLO_IOCTL_RESETLANG _IO(

9、HELLO_MAGIC,0)  //设置复位,这个命令不带参数 #define HELLO_IOCTL_GETLANG  _IOR(HELLO_MAGIC,1,int) //获取当前设备的语言类型参数,参数是int型 #define HELLO_IOCTL_SETLANG  _IOW(HELLO_MAGIC,2,int) //设置设备的语言类型,参数是int型   多的不说了,下面贴上完整代码,懒人没写注释。。不好意思。 hello_mod.c [cpp] view plaincopyprint? /*   * =================================

10、   *   *       Filename:  hello.c   *   *    Description:  hello_mod   *   *        Version:  1.0   *        Created:  01/28/2011 05:07:55 PM   *       Revision:  none   *       Compiler:  gcc   *   *         Author:  Tishion (shion), ti

11、shion@   *        Company:  LIM   *   * =====================================================================================   */         #include     #include     #include     #include     #include     #include 

12、    #include     #include     #include     #include     #include     #include     #include "hello_mod_ioctl.h"       #define MAJOR_NUM 250    #define MINOR_NUM 0    #define IN_BUF_

13、LEN 256    #define OUT_BUF_LEN 512       MODULE_AUTHOR("Tishion");   MODULE_DESCRIPTION("Hello_mod driver by tishion");      static struct class * hello_class;   static struct cdev hello_cdev;   static dev_t devnum = 0;   static char * modname = "hello_mod";   static char * devicename = "h

14、ello";   static char * classname = "hello_class";      static int open_count = 0;   static struct semaphore sem;   static spinlock_t spin = SPIN_LOCK_UNLOCKED;   static char * inbuffer = NULL;   static char * outbuffer = NULL;   static lang_t langtype;      static int hello_mod_open(struct

15、 inode *, struct file *);   static int hello_mod_release(struct inode *, struct file *);   static ssize_t hello_mod_read(struct file *, char *, size_t, loff_t *);   static ssize_t hello_mod_write(struct file *, const char *, size_t, loff_t *);   static int hello_mod_ioctl(struct inode *, struct 

16、file *, unsigned int, unsigned long);      struct file_operations hello_mod_fops =    {       .owner = THIS_MODULE,       .open = hello_mod_open,       .read = hello_mod_read,       .write = hello_mod_write,       .ioctl = hello_mod_ioctl,       .release = hello_mod_release,   };      st

17、atic int hello_mod_open(struct inode *inode, struct file *pfile)   {       printk("+hello_mod_open()!/n");       spin_lock(&spin);       if(open_count)       {           spin_unlock(&spin);           return -EBUSY;       }       open_count++;       spin_unlock(&spin);       printk("-hello

18、mod_open()!/n");       return 0;   }   static int hello_mod_release(struct inode *inode, struct file *pfile)   {       printk("+hello_mod_release()!/n");       open_count--;       printk("-hello_mod_release()!/n");       return 0;   }   static ssize_t hello_mod_read(struct file *pfile, ch

19、ar *user_buf, size_t len, loff_t *off)   {       printk("+hello_mod_read()!/n");          if(down_interruptible(&sem))       {           return -ERESTARTSYS;        }       memset(outbuffer, 0, OUT_BUF_LEN);       printk("    +switch()/n");       switch(langtype)       {           case e

20、nglish:               printk("        >in case: english/n");               sprintf(outbuffer, "Hello! %s.", inbuffer);               break;           case chinese:               printk("        >in case: chinese/n");               sprintf(outbuffer, "你好! %s.", inbuffer);               break; 

21、          case pinyin:               printk("        >in case: pinyin/n");               sprintf(outbuffer, "ni hao! %s.", inbuffer);               break;           default:               printk("        >in case: default/n");               break;       }       printk("    -switch()/n");  

22、     if(copy_to_user(user_buf, outbuffer, len))       {           up(&sem);           return -EFAULT;       }       up(&sem);       printk("-hello_mod_read()!/n");       return 0;   }   static ssize_t hello_mod_write(struct file *pfile, const char *user_buf, size_t len, loff_t *off)   {  

23、     printk("+hello_mod_write()!/n");       if(down_interruptible(&sem))       {           return -ERESTARTSYS;       }       if(len > IN_BUF_LEN)       {           printk("Out of input buffer/n");           return -ERESTARTSYS;       }       if(copy_from_user(inbuffer, user_buf, len))  

24、    {           up(&sem);           return -EFAULT;       }       up(&sem);          printk("-hello_mod_write()!/n");       return 0;   }   static int hello_mod_ioctl(struct inode *inode, struct file *pfile, unsigned int cmd, unsigned long arg)   {       int err = 0;       printk("+hello_

25、mod_ioctl()!/n");       printk("    +switch()/n");       switch(cmd)       {           case HELLO_IOCTL_RESETLANG:               printk("        >in case: HELLO_IOCTL_RESETLANG/n");               langtype = english;               break;           case HELLO_IOCTL_GETLANG:               prin

26、tk("        >in case: HELLO_IOCTL_GETLANG/n");               err = copy_to_user((int *)arg, &langtype, sizeof(int));               break;           case HELLO_IOCTL_SETLANG:               printk("        >in case: HELLO_IOCTL_SETLANG/n");               err = copy_from_user(&langtype,(int *)arg,

27、 sizeof(int));               break;           default:               printk("        >in case: default/n");               err = ENOTSUPP;               break;       }       printk("    -switch()/n");       printk("-hello_mod_ioctl()!/n");       return err;   }   static int __init hello_mo

28、d_init(void)   {       int result;       printk("+hello_mod_init()!/n");       devnum = MKDEV(MAJOR_NUM, MINOR_NUM);       result = register_chrdev_region(devnum, 1, modname);          if(result < 0)       {           printk("hello_mod : can't get major number!/n");           return result

29、       }             cdev_init(&hello_cdev, &hello_mod_fops);       hello_cdev.owner = THIS_MODULE;       hello_cdev.ops = &hello_mod_fops;       result = cdev_add(&hello_cdev, devnum, 1);       if(result)           printk("Failed at cdev_add()");       hello_class = class_create(THIS_MODU

30、LE, classname);       if(IS_ERR(hello_class))       {           printk("Failed at class_create().Please exec [mknod] before operate the device/n");       }       else       {           device_create(hello_class, NULL, devnum,NULL, devicename);       }          open_count = 0;       langty

31、pe = english;       inbuffer = (char *)kmalloc(IN_BUF_LEN, GFP_KERNEL);       outbuffer = (char *)kmalloc(OUT_BUF_LEN, GFP_KERNEL);       init_MUTEX(&sem);       printk("-hello_mod_init()!/n");       return 0;   }      static void __exit hello_mod_exit(void)   {       printk("+hello_mod_ex

32、it!/n");       kfree(inbuffer);       kfree(outbuffer);       cdev_del(&hello_cdev);       device_destroy(hello_class, devnum);       class_destroy(hello_class);       unregister_chrdev_region(devnum, 1);       printk("-hello_mod_exit!/n");       return ;   }      module_init(hello_mod_in

33、it);   module_exit(hello_mod_exit);   MODULE_LICENSE("GPL");       hello_mod_iotcl.h [cpp] view plaincopyprint? /*   * =====================================================================================   *   *       Filename:  hello_mod_ioctl.h   *   *    Description:  define the cmd 

34、supported by hello_mod   *   *        Version:  1.0   *        Created:  06/19/2011 10:24:20 PM   *       Revision:  none   *       Compiler:  gcc   *   *         Author:  Tishion (shion), tishion@   *        Company:  LIM   *   * ===========================================================

35、   */      #ifndef __HELLO_MOD_IOCTL_H__    #define __HELLO_MOD_IOCTL_H__       #define HELLO_MAGIC 12    #define HELLO_IOCTL_RESETLANG   _IO(HELLO_MAGIC,0)      //set langtype = english    #define HELLO_IOCTL_GETLANG     _IOR(HELLO_MAGIC,1,int) //get langtype    #

36、define HELLO_IOCTL_SETLANG     _IOW(HELLO_MAGIC,2,int) //set langtype       typedef enum _lang_t   {       english, chinese, pinyin   }lang_t;      #endif       Makefile #**********************************************    # Makefile linux 2.6 Module     # This makefile is written for Ubu

37、ntu 10.10    # It may not perfomance without erros on the    # other version or distributions.    #**********************************************    #   BY:tishion    #   Mail:tishion@    #   2011/06/19    #**********************************************    obj-m += hello_mod.o   CURRENT_PAT

38、H := $(shell pwd)   LINUX_KERNEL := $(shell uname -r)   LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)   all:       make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules   clean:       make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean   install:       insmod hello_mod.ko  

39、unistall:       rmmod hello_mod       附上一用户层测试文件,编译后需要root身份执行。 /*   * =====================================================================================   *   *       Filename:  hell_mod_test.c   *   *    Description:  hell_mod test app   *   *        Version:  1.0   *        Create

40、d:  06/20/2011 01:44:11 AM   *       Revision:  none   *       Compiler:  gcc   *   *         Author:  Tishion (shion), tishion@   *        Company:  LIM   *   * =====================================================================================   */      #include     #include 

41、    #include     #include     #include     #include     #include     #include     #include "../hello_mod_ioctl.h"       int main()   {       char outbuf[512];       char * myname = "tishion";       lang_t lang

42、type = english;       int fd = open("/dev/hello", O_RDWR, S_IRUSR|S_IWUSR);       if(fd != -1)       {           write(fd, myname, strlen(myname)+1);           langtype = chinese;           ioctl(fd, HELLO_IOCTL_SETLANG, &langtype);           read(fd, outbuf, 512);           printf("langtype

43、chinese:%s/n", outbuf);           memset(outbuf, 0, 512);           langtype = pinyin;           ioctl(fd, HELLO_IOCTL_SETLANG, &langtype);           read(fd, outbuf, 512);             printf("langtype=pinyin:%s/n", outbuf);           memset(outbuf, 0, 512);           ioctl(fd, HELLO_IOCTL_RESETLANG, &langtype);               read(fd, outbuf, 512);           printf("langtype=english:%s/n", outbuf);       }       else       {           perror("Failed at open():");       }       return 0;   }       编译和运行过程图        

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服