Z16300
驱动牛犊
驱动牛犊
  • 注册日期2002-06-04
  • 最后登录2018-01-17
  • 粉丝3
  • 关注0
  • 积分88分
  • 威望239点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1849回复:2

发现执行读操怍,总在verify_area函数退出?

楼主#
更多 发布于:2005-03-26 11:12
我的驱动源文件:
#ifndef __KERNEL__
# define __KERNEL__
#endif
#ifndef MODULE
# define MODULE
#endif

#include <linux/config.h>
#include <linux/module.h>

MODULE_LICENSE(\"GPL\");
#ifdef CONFIG_SMP
#define __SMP__
#endif

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
unsigned int test_major = 0;

static int read_hello(struct inode *node,struct file *file,char *buf,int count);
static int write_hello(struct inode *inode, struct file *file, const char *buf, int count);
static int open_hello(struct inode *inode, struct file *file );
static void release_hello(struct inode *inode, struct file *file );

struct file_operations hello_fops= {
  read: read_hello,
  write: write_hello,
  open: open_hello,
  release: release_hello,
};

static int init_module()
{
  printk(\"init_module!\\n\");
  int result;

  result = register_chrdev(0, \"hello\", &hello_fops);

  if (result < 0) {
    printk(KERN_INFO \"test: can\'t get major number\\n\");
    return result;
  }

  if (test_major == 0)
    test_major = result; /* dynamic */
    
  return 0;
}

static void cleanup_module()
{
  printk(\"cleanup_module!\\n\");
  unregister_chrdev(test_major, \"hello\");
}

static int read_hello(struct inode *node,struct file *file,char *buf,int count)
{
  printk(\"read_hello!\\n\");

  int left,i;
  int buffer[10];
  
  for(i=0; i<10; i++)
    buffer = 1;

  if (verify_area(VERIFY_WRITE, buf, count) == -EFAULT )
    return -EFAULT;

  for(left = count ; left > 0 ; left--)
  {
    copy_to_user(buf, buffer, 10);
    buf++;
  }

  for(i=0; i<10; i++)
    printk(\"buf[%d]: %d\\n\",i, buf);
  
  return count;
}

static int write_hello(struct inode *inode, struct file *file, const char *buf, int count)
{
  return count;
}

static int open_hello(struct inode *inode, struct file *file )
{
  MOD_INC_USE_COUNT;
  return 0;
}

static void release_hello(struct inode *inode, struct file *file )
{
  MOD_DEC_USE_COUNT;
}


测试程序:

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

main()

{

  int testdev;

  int i;

  char buf[10];

  testdev = open(\"/dev/hello\",O_RDWR);

  if ( testdev == -1 )

  {

    printf(\"Cann\'t open file \\n\");

    exit(0);

  }

  read(testdev,buf,10);

  for (i = 0; i < 10;i++)

    printf(\"%d\\n\",buf);


  close(testdev);

}


发现执行读操怍,总在verify_area函数退出?
Z16300
驱动牛犊
驱动牛犊
  • 注册日期2002-06-04
  • 最后登录2018-01-17
  • 粉丝3
  • 关注0
  • 积分88分
  • 威望239点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2005-03-26 11:13
我用的是linux8.0,内核版本是2.4.18
wdss12345
驱动牛犊
驱动牛犊
  • 注册日期2005-04-09
  • 最后登录2005-04-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-04-09 13:58
for(left = count ; left > 0 ; left--)
{
copy_to_user(buf, buffer, 10);
buf++;
}
这里有问题,你是连着10次copy10字节buuffer的内容到用户空间了,自然会出错,
copy_to_user(buf, buffer, count);就行了
游客

返回顶部