⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chardev.c

📁 这是一个我经过研究学习,理解了别人得程序,感觉很不错的源程序.
💻 C
字号:
#ifndef __KERNEL__#  define __KERNEL__#endif#ifndef   MODULE#  define MODULE#endif#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/malloc.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/types.h>#include <linux/proc_fs.h>#include <linux/fcntl.h>#include <asm/system.h>#include "chardev.h"long chardev_buflen=CHARDEV_BUFLEN;int chardev_major=CHARDEV_MAJOR;CHAR_DEV *char_dev;MODULE_PARM(chardev_major,"i");MODULE_AUTHOR("Lipeng,BUAA");#ifdef CHARDEV_DEBUG /* use proc only if debugging *//*  * The proc filesystem: function to read and entry */int chardev_read_procmem(char *buf, char **start, off_t offset, int count, int *eof, void *data){    }#endifstruct  file_operations chardev_fops = {  open:   chardev_open,  release:chardev_release,  read:   chardev_read,  write:  chardev_write,};int chardev_trim(CHAR_DEV* dev){  if (dev->data)  {    kfree(dev->data);    dev->data=NULL;  }  return 0;}int chardev_open(struct inode *inode, struct file *filp){  CHAR_DEV *dev;  dev=(CHAR_DEV*)filp->private_data;  if (!dev)  {    dev=char_dev;    filp->private_data=dev;  }    MOD_INC_USE_COUNT;  if ((filp->f_flags & O_ACCMODE)==O_WRONLY)  {    if (down_interruptible(&dev->sem))    {      MOD_DEC_USE_COUNT;      return -ERESTARTSYS;    }    chardev_trim(dev);    up(&dev->sem);  }  return 0;}int chardev_release(struct inode *inode, struct file *filp){  MOD_DEC_USE_COUNT;  return 0;}ssize_t chardev_read(struct file *filp, char *buf, size_t count, loff_t *f_pos){  CHAR_DEV *dev=filp->private_data;  ssize_t ret=0;  if (down_interruptible(&dev->sem))    return -ERESTARTSYS;  if (*f_pos>=chardev_buflen)    goto out;  if (*f_pos+count>chardev_buflen)    count=chardev_buflen-(long)*f_pos;  if (copy_to_user(buf,dev->data+*f_pos,count))  {    ret=-EFAULT;    goto out;  }  *f_pos+=count;  ret=count; out:  up(&dev->sem);  return ret;}ssize_t chardev_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos){  CHAR_DEV *dev=filp->private_data;  ssize_t ret=0;  if (down_interruptible(&dev->sem))    return -ERESTARTSYS;  if (*f_pos>=chardev_buflen)    goto out;  if (count>chardev_buflen-(long)*f_pos)    count=chardev_buflen-(long)*f_pos;  if (!dev->data) {    dev->data=kmalloc(chardev_buflen,GFP_KERNEL);    if (!dev->data)      goto out;    memset(dev->data,0,chardev_buflen);  }  if (copy_from_user(dev->data+(long)*f_pos,buf,count))  {    ret=-EFAULT;    goto out;  }  *f_pos+=count;  ret=count; out:  up(&dev->sem);  return ret;}/*lofft chardev_llseek(struct file *filp, loff_t f_pos, int count){  if (  }*/int chardev_init_module(void){  int ret=0;  SET_MODULE_OWNER(&chardev_fops);  ret=register_chrdev(chardev_major,"chardev",&chardev_fops);  if (ret<0)  {    printk(KERN_WARNING "chardev:can't get major:%d\n",chardev_major);    return ret;  }  if (chardev_major==0)    chardev_major=ret;  char_dev=kmalloc(sizeof(CHAR_DEV),GFP_KERNEL);  if (char_dev==NULL)  {    printk(KERN_WARNING "error to allocate DEVICE char_dev\n");    ret=-ENOMEM;    goto fail;  }    memset(char_dev,0,sizeof(CHAR_DEV));  sema_init(&(char_dev->sem),1);  printk("init module succeed\n");  EXPORT_NO_SYMBOLS;  return 0; fail:  chardev_cleanup_module();  return ret;}void chardev_cleanup_module(void){  unregister_chrdev(chardev_major,"chardev");  kfree(char_dev->data);  kfree(char_dev);}module_init(chardev_init_module);module_exit(chardev_cleanup_module);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -