生活随笔
收集整理的這篇文章主要介紹了
Linux设备驱动入门----globalmem字符设备驱动
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1、什么是globalmem虛擬設(shè)備
(1)、globalmem字符設(shè)備驅(qū)動(dòng)中,分配一片內(nèi)存大小為GLOBALMEM_SIZE(4K)的空間
(2)、提供對(duì)該片內(nèi)存的讀寫、控制和定位函數(shù)
(3)、用戶進(jìn)程能夠通過(guò)linux系統(tǒng)調(diào)用訪問(wèn)這篇內(nèi)存
[cpp]?view plaincopy
#include?<linux/module.h>?? #include?<linux/init.h>?? #include?<linux/types.h>?? #include?<linux/fs.h>?? #include?<linux/errno.h>?? #include?<linux/mm.h>?? #include?<linux/sched.h>?? #include?<linux/cdev.h>?? #include?<asm/io.h>?? #include?<asm/system.h>?? #include?<asm/uaccess.h>?? ?? #define?GLOBALMEM_SIZE?0X1000?/*全局內(nèi)存最大4KB*/?? #define?MEM_CLEAR?0x1?/*清零全局內(nèi)存*/?? #define?GLOBALMEM_MAJOR?254??/*?預(yù)設(shè)的globalmem?的主設(shè)備號(hào)?*/ ?? static?globalmem_major?=?GLOBALMEM_MAJOR;?? ?? ?? struct?globalmem_dev?? {?? ?struct?cdev?cdev;???? ?unsigned?char?mem[GLOBALMEM_SIZE);???? };?? ?? struct?globalmem_dev?*globalmem_devp;???? ?? ?? int?globalmem_open(struct?inode?*inode,struct?file?*filp)?? {?? ?filp->private_data?=?globalmem_devp;??? ?return?0?? }?? ?? ?? int?globalmem_release(struct?inode?*inode,struct?file?*filp)?? {?? ?return?0;?? }?? ?? ?? static?int?globalmen_ioctl(struct?inode?*inodep,struct?file?*filp,unsigned?int?cmd,unsigned?long?arg)?? {?? ?struct?globalmen_dev?*dev?=?filp->private_data;??? ?switch(cmd)?? ?{?? ??case??MEE_CLEAR:?? ???memset(dev->mem,0,GLOBALMEM_SIZE);?? ???printk(KERN_INFO"globalmem?is?set?to?zero\n);?? ???break;?? ??default:?? ???return?-EINVAL;?? ?}?? ?return?0;?? }?? ?? ?? static?ssizez_t?globalmem_read(struct?file?*filp,char?__user?*buf,size_t?size,loff_t?*opps)?? {?? ?unsigned?long?p?=?*ppos;?? ?unsigned?int?count?=?size;?? ?int?ret?=?0;?? ?struct?globalmem_dev?*dev?=?filp->private_data;??? ??? ?if(p?>=?GLOBALMEM_SIZE)???? ?{?? ??return?count???-ENXIO:0;?? ?}?? ?if(count?>?GLOBAL_SIZE?-?P)?? ?{?? ??count?=?GLOBALMEN_SIZE?-?P;?? ?}?? ??? ?if(copy_to_user(buf,(void?*)(dev->mem+p),count))???? ?{?? ??ret?=?-ENAU;T;?? ?}?? ?else?? ?{?? ??*oppos?+=?count;?? ??ret?=?count;?? ??printk(KERN_INFO"read?%d?bytes(s)?from?%d\n",count,p);?? ?}?? ?return?ret;?? }?? ?? ?? static?ssize_t?globalmem_write(struct?file?*filp,const?char?__user?*buf,size_t?size,loff_t?*ppos)?? {?? ?unsigned?long?*p?=?*ppos;?? ?unsigned?int?count?=?size;?? ?int?ret;?? ??? ?struct?globalmem_dev?*dev?=?filp->private_data;?? ??? ?if(p?>=?CLOBALMEM_SIZE)???? ?{?? ??return?count??-ENXIO:0;?? ?}?? ??? ?if(count?>?GLOBALMEN_SIZE?-?P)??? ?{?? ??count?=?CLOBALMEN_SIZE?-?P;?? ?}?? ??? ?if(copy_from_user(dev->mem?+?p,buf,count))??? ?{?? ??ret?=?-ENAULT;?? ?}?? ?else?? ?{?? ??*ppos?=+?count;?? ??ret?=?count;?? ??printk(KERN_INFO"written?%d?bytes(s)?from?%d\n",count,p);?? ?}?? ?return?ret;?? }?? ?? ?? static?loff_t?globalmem_llseek(struct?file?*filp,loff_t?offset,int?orig)?? {?? ?loff_t?ret?=?0;?? ?switch(orig)?? ?{?? ??case?0:????? ???if(offset?<0?)?? ???{?? ????ret?=?-EINVAL;?? ????break;?? ???}?? ????? ???if((unsigned?int?)offset?>?GLOBALMEM_SIZE)?? ???{?? ????ret?=?-?EINVAL;?? ????break;?? ???}?? ???filp->f_ops?=?(unsigned?int)offset;?? ???ret?=?filp->f_pos;?? ???break;?? ????? ??case?1:????? ???if((filp->f_ops?+?offset)?>?GLOBALMEMSIZE)?? ???{?? ????ret?=?-EINVAL;?? ????break;?? ???}?? ???if((filp->f_ops?+?offset)<0)?? ???{?? ????ret?=?-ENVAL;?? ????break;?? ???}?? ???filp->f_ops?+=offset;?? ???ret?=?filp->f_ops;?? ???break;?? ??default:?? ???ret?=?-EINVAL;?? ???break;??? ?}?? ?return?ret;?? }?? ?? ?? static?const?struct?file_operations?globalmem_fops=?? {?? ?.owner?=?THIS_MODULE;?? ?.llseek?=?globalmem_llseek;?? ?.read?=?globalmem_read;?? ?.write?=?globalmem_write;?? ?.ioctl?=?globalmem_ioctl;?? ?.open?=?globalmem_open;?? ?.release?=?globalmem_release;?? };?? ?? ?? static?void?globalmem_setup_cdev(struct?globalmem_dev?*dev,int?index)?? {?? ?int?err,devno?=?MKDEV(globalmen_major,index);?? ?cdev_init(&dev->cdev,&globalmem_fops);?? ?dev->cdev.owner?=?THIS_MOUDEL;?? ?dev->cdev.ops?=?&golbalmem_fops;?? ?err?=?cdev_add(&dev->cdev,devno,1);?? ?if(err)?? ?{?? ??printk(KERN_NOTICE"Error?%d?adding?LED%d",err,index);?? ?}?? ??? }?? ?? ?? static?int?__init?globalmem_init(void)?? {?? ?int?result;?? ?dev_t?devno?=?MKDEV(globalmem_major,0);?? ??? ?if(globalmem_major)??? ?{?? ??result?=?register_chrdev-region(devno,1,"globalmem");?? ?}?? ?else???? ?{?? ??result?=?alloc_chrdev_region(&devno,0,1,"globalmem");?? ??globalmem_major?=?MAJOR(devno);?? ?}?? ??? ?if(result?<?0)?? ?{?? ??return?result;?? ?}?? ??? ?globalmem_devp?=?kmalloc(sizeof(struct?globalmem_dev),GFP_KERNEL);??? ?if(!globalmem_devp)?? ?{?? ??result?=?-ENOMEM;?? ??goto?fail_malloc;?? ?}?? ??? ?memset(globalmem_devp,0,sizeof(struct?globalmem_dev));?? ?globalmem_setup_cdev(globalmem_devp,0);?? ?return?0;?? ??? ?fail_malloc:unregister_chrdev_region(devno,1);?? ?return?result;?? }?? ?? ?? void?__eixt?globalmem_exit(void)?? {?? ?cdev_del(&globalmem_devp->cdev);??? ?kfree(globalmem_devp);???????????? ?unregister_chrdev_region(MKDEV(globalmem_major,0),1);??? }?? ?? MODULE_AUTHOR("NOODLE");?? MODULE_LICENSE("GPL");?? ?? mdule_param(globalmem_major,int,S_IRUGO);?? ?? module_init(globalmem_init);?? module_exit(globalmem_exit); ??
總結(jié)
以上是生活随笔為你收集整理的Linux设备驱动入门----globalmem字符设备驱动的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。