linux裝置驅動–globalmem字元裝置

來源:互聯網
上載者:User

開發環境:Winxp(主機)+ VisualBox +fedora9(虛擬機器2.6.25.4核心)

功能:   globalmem字元裝置架構分析(支援2個裝置),裝置檔案動態建立

#include <linux/module.h>#include <linux/types.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/mm.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/cdev.h>#include <linux/device.h>#include <asm/io.h>#include <asm/system.h>#include <asm/uaccess.h>#define GLOBALMEM_SIZE 0x1000//global mem size#define GLOBALMEM_MAJOR 238//major number#define MEM_CLEAR 0x1 //clear global memstatic int globalmem_major=GLOBALMEM_MAJOR;static struct class *globalmem_class;struct globalmem_dev{struct cdev cdev;unsigned char mem[GLOBALMEM_SIZE];};struct globalmem_dev *globalmem_devp;static int globalmem_open(struct inode *inode,struct file *filp){struct globalmem_dev *dev;dev=container_of(inode->i_cdev,struct globalmem_dev,cdev);filp->private_data=dev;return 0;}static int globalmem_release(struct inode *inode,struct file *filp){return 0;}static ssize_t globalmem_read(struct file *filp,char __user *buf,size_t count,loff_t *ppos){unsigned long p=*ppos;int ret=0;struct globalmem_dev *dev=filp->private_data;if(p>GLOBALMEM_SIZE)return 0;if(count>GLOBALMEM_SIZE-p)count=GLOBALMEM_SIZE-p;if(copy_to_user(buf,(void*)(dev->mem+p),count))ret= -EFAULT;else{*ppos+=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 count,loff_t *ppos){unsigned long p=*ppos;int ret=0;struct globalmem_dev *dev=filp->private_data;if(p>GLOBALMEM_SIZE)return 0;if(count>GLOBALMEM_SIZE-p)count=GLOBALMEM_SIZE-p;if(copy_from_user(dev->mem+p,buf,count))ret=-EFAULT;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;switch(orig){case 0:if(offset<0){ret=-EINVAL;break;}if(offset>GLOBALMEM_SIZE){ret=-EINVAL;break;}filp->f_pos=(unsigned int)offset;ret=filp->f_pos;break;case 1:if((filp->f_pos+offset)>GLOBALMEM_SIZE){ret=-EINVAL;break;}if((filp->f_pos+offset)<0){ret=-EINVAL;break;}filp->f_pos+=offset;ret=filp->f_pos;break;default:ret=-EINVAL;}return ret;}static int globalmem_ioctl(struct inode *inodep,struct file *filp,unsigned int cmd,unsigned long arg){struct globalmem_dev *dev=filp->private_data;switch(cmd){case MEM_CLEAR:memset(dev->mem,0,GLOBALMEM_SIZE);printk(KERN_INFO "globalmem is set to zero\n");break;default:return -EINVAL;}return 0;}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(globalmem_major,index);cdev_init(&dev->cdev,&globalmem_fops);dev->cdev.owner=THIS_MODULE;err=cdev_add(&dev->cdev,devno,1);if(err)printk(KERN_NOTICE "ERROR %d adding globalmem %d",err,index);}int globalmem_init(void){int result;dev_t devno=MKDEV(globalmem_major,0);if(globalmem_major)result=register_chrdev_region(devno,2,"globalmem");else{result=alloc_chrdev_region(&devno,0,2,"globalmem");globalmem_major=MAJOR(devno);}if(result<0)return result;globalmem_devp=kmalloc(2*sizeof(struct globalmem_dev),GFP_KERNEL);if(!globalmem_devp){result=-ENOMEM;goto fail_malloc;}memset(globalmem_devp,0,2*sizeof(struct globalmem_dev));globalmem_setup_cdev(&globalmem_devp[0],0);globalmem_setup_cdev(&globalmem_devp[1],1);globalmem_class=class_create(THIS_MODULE,"globalmem");if(IS_ERR(globalmem_class))     { printk(KERN_INFO " create class faild!\n"); return -1;     } class_device_create(globalmem_class, NULL, MKDEV(globalmem_major, 0),NULL,"globalmem%d",0); class_device_create(globalmem_class, NULL, MKDEV(globalmem_major, 1),NULL,"globalmem%d",1);return 0;fail_malloc:unregister_chrdev_region(devno,1);return result;}void globalmem_exit(void){cdev_del(&globalmem_devp->cdev);kfree(globalmem_devp);unregister_chrdev_region(MKDEV(globalmem_major,0),1);class_device_destroy(globalmem_class, MKDEV(globalmem_major, 0));  class_device_destroy(globalmem_class, MKDEV(globalmem_major, 1));    class_destroy(globalmem_class); }module_param(globalmem_major,int,S_IRUGO);module_init(globalmem_init);module_exit(globalmem_exit);MODULE_LICENSE("GPL");

遇到的錯誤:

1、globalmem_write中的 const char __user *buf沒有加const,編譯的時候提示了,自己沒有注意結果出現段錯誤。

2、類裝置檔案的建立的時候要用class_device_create().

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.