当前位置:  技术问答>linux和unix

操纵一块内存区的驱动函数

    来源: 互联网  发布时间:2016-06-26

    本文导语:  这是一个操纵一块内存区的驱动函数,当系统以调用ioctl函数国MEM_CLEAR和 MEM_SETSIZE时,就立刻卡住了 然后键盘上数字键盘的指示灯灭掉,另外两个指示灯不停的闪,不知道是怎么回事?  mdri.h #ifndef _MDRI_H #define _MDRI_H...

这是一个操纵一块内存区的驱动函数,当系统以调用ioctl函数国MEM_CLEAR和 MEM_SETSIZE时,就立刻卡住了 然后键盘上数字键盘的指示灯灭掉,另外两个指示灯不停的闪,不知道是怎么回事? 
mdri.h

#ifndef _MDRI_H
#define _MDRI_H

#include 

#define MEM_CLEAR _IO('k',1)

#define MEM_RE  _IO('k',2)

#define MEM_SETSIZE _IOW('k',3,unsigned long)

#endif

mdri.c

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include "mdri.h"



#define GLOBALMEM_SIZE 0x1000

#define GLOBALMEM_MAJOR 255



struct globalmem_dev

{

unsigned int count;

int size;

struct cdev cd;

unsigned char mem[GLOBALMEM_SIZE];

};

struct globalmem_dev *g_dev;

struct file_operations globalmem_fopes;

int globalmem_major=GLOBALMEM_MAJOR;



int globalmem_open(struct inode *inode,struct file *filp)

{

  filp->private_data=g_dev;

  g_dev->count++;

  return 0;

}



int globalmem_release(struct inode *inode,struct file *filp)

{

  if(g_dev->count>0)

    g_dev->count--;

  return 0;

}



int globalmem_ioctl(struct inode *inodep,

  struct file *filp,unsigned int cmd,unsigned long arg)

{
  int i;
  //unsigned long karg;

  int karg;
  char c;

  switch(cmd)

  {

    case MEM_CLEAR:

      memset(g_dev->mem,0,g_dev->size);
      g_dev->size=0;

      printk(KERN_EMERG "MEM_CLEAR g_dev->size=%in",g_dev->size);

      break;

    case MEM_RE:

      if(g_dev->count!=1)

        return -1;

      for(i=0;isize)/2;i++){

        c=g_dev->mem[i];

        g_dev->mem[i]=g_dev->mem[g_dev->size-i-1];

        g_dev->mem[g_dev->size-i-1]=c;

      }
      printk(KERN_EMERG "MEM_RE g_dev->size=%in",g_dev->size);

      break;

    case MEM_SETSIZE:
      if(access_ok(VERIFY_READ,&arg,sizeof(unsigned long)))
      {
        printk(KERN_EMERG "read arg error1n");

        return -EFAULT;
      }
      if(get_user(karg,(__user int *)arg))
      {
        printk(KERN_EMERG "read arg error2n");

        return -EFAULT;
      }

      if(kargGLOBALMEM_SIZE)

        break;

      g_dev->size=(int)karg;
      printk(KERN_EMERG "MEM_SETSIZE g_dev->size=%i,karg=%in",g_dev->size,karg);

      break;

    default:

      return  - EINVAL;

  }

  return 0;

}



int globalmem_read(struct file *filp,char __user *buf,

  size_t size,loff_t *ppos)

{

  unsigned long pos=*ppos;

  unsigned long count=size;

  printk(KERN_INFO "readn");
  printk("%cn",g_dev->mem[0]);

  if(access_ok(VERIFY_WRITE,buf,count)==-EFAULT)

  {

    printk(KERN_INFO "read error1n");

    return -EFAULT;

  }

  if(*ppos+count>g_dev->size)

    count=g_dev->size-(*ppos);

  if(copy_to_user(buf,(void*)(g_dev->mem+pos),count))

  {

    printk(KERN_INFO "read error2n");

    return -EFAULT;

  }

  *ppos+=count;

  printk("%sn",g_dev->mem);
  printk(KERN_INFO "read overn");

  return count;

}



int globalmem_write(struct file *filp,char __user *buf,

  size_t size,loff_t *ppos)

{
  printk(KERN_INFO "writen");
  printk("%cn",g_dev->mem[0]);

  if(g_dev->count!=1)

  {

    printk(KERN_INFO "write error:g_dev!=1n");

    return -EFAULT;

  }

  unsigned long real_size;

  if(size+(g_dev->size) > GLOBALMEM_SIZE)

    real_size=GLOBALMEM_SIZE;

  else

    real_size=size;

  

  if(copy_from_user((g_dev->mem)+g_dev->size,(void *)buf,real_size))

  {

    printk(KERN_INFO "write error 1n");

    return -EFAULT;

  }

  g_dev->size+=real_size;

  printk("%sn",g_dev->mem);
  printk(KERN_INFO "write overn");

  return real_size;

}



loff_t globalmem_llseek(struct file *filp,loff_t offset,int orig)

{

  switch(orig)

  {

    case 0://from the begin of the file

      if(offset GLOBALMEM_SIZE)

        return -EFAULT;

      filp->f_pos=(unsigned int)offset;

      return offset;

    case 1://from the current of the file

      if(filp->f_pos+offset>GLOBALMEM_SIZE || filp->f_pos+offsetf_pos+=offset;

      return filp->f_pos;

    case 2://from the end of the file

      if(offset>0 || offset+g_dev->sizef_pos=(unsigned int)(offset+g_dev->size);

      return filp->f_pos;

    default:

      return -EFAULT;

  }

}



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(&g_dev->cd,&globalmem_fops);

  g_dev->cd.owner=THIS_MODULE;

  g_dev->cd.ops=&globalmem_fops;

  err=cdev_add(&g_dev->cd,devno,1);

  if(err)

    printk(KERN_NOTICE "Error %d adding LED%d", err, index);

}



int 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(resultsize=0;
  g_dev->count=0;

  globalmem_setup_cdev(g_dev,0);

  return 0;

}



void globalmem_exit(void)

{

  cdev_del(&g_dev->cd);

  kfree(g_dev);

  unregister_chrdev_region(MKDEV(globalmem_major, 0), 1);

}



MODULE_AUTHOR("BLACK & WHITE");

MODULE_LICENSE("Dual BSD/GPL");



module_param(globalmem_major, int, S_IRUGO);



module_init(globalmem_init);

module_exit(globalmem_exit);

|
#define GLOBALMEM_SIZE 0x1000
这里开的太大了,用
#define GLOBALMEM_SIZE 0x100

|
g_dev->size 赋值的语句好多条呢,难道都去掉?

|
楼主这个程序是Linux设备驱动开发入门与编程实践这本书中的,
这本书说实话,我感觉水平很一般,错误百出,
它给的globalmem驱动本身就有问题~

建议换一个例程学习~

|
友情帮顶,一起学习。

|
帮顶。

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Java 字节码操纵框架 ASM
  • iOS 操纵杆 Fancy Schmancy Joystick
  • JBuilder开发B/S数据库应用好用吗?有没有类似Delphi的数据操纵功能?
  • 我要用jsp操纵一个文本文件,怎么设置路径
  • 请问APPLICATION怎样启动一个IE窗口,怎样操纵窗口
  • 如何在unix c++程序中操纵ini文件,有现成的类库吗?急!!!
  • 如何在UNIX上通过ODBC操纵Oracle等DBMS???
  • 为什么我下载的RedHat Linux 被检测未知的操纵系统???
  • 各位高手:怎样用java applet 操纵DHTML ? 恳请指教,高分在所不惜,要多少加多少!!
  • 烦人:用Java操纵mySQL数据库时的中文字符处理。
  • c/c++ iis7站长之家
  • 如何利用tinyxml操纵xml及注意问题
  • 用C#操纵IIS(代码)
  • 谁能给些JAVA操纵LDAP的例子?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3