Linux内核copy_to_user向用户空间显示不同的结果

时间:2012-02-14 16:09:54

标签: linux-kernel

使用此应用程序从用户空间读取一些错误。我的copy_to_user不正确吗?

以下是终端的读数:

Press r to read from device or w to write the device r
0x-1075024108 0x15123440 0xe70401 0xe6f8dc 0xe73524 
0x0 0x15037588 0xbfec6f14 0xe57612 0xbfec6f34 
0x15037140 0x2 0xe57334 0xc6d690 0xd696910 
0x-1075024080 0x15071734 0xc737c9 0x804835a 0x2 

以下是应用层的代码:

read(fd, read_buf, sizeof(read_buf));

for(i=0;i<=(BUFF_SIZE / sizeof(int));i+=5)
    printf(" 0x%x 0x%x 0x%x 0x%x 0x%x \n", 
        read_buf[i],read_buf[i+1],read_buf[i+2],
        read_buf[i+3],read_buf[i+4]);
break;

以下是我的驱动程序代码:

#include <linux/version.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#ifdef MODVERSIONS
#  include <linux/modversions.h>
#endif
#include <asm/io.h>
#include <asm/uaccess.h> // required for copy_from and copy_to user 

/* character device structures */
static dev_t mmap_dev;
static struct cdev mmap_cdev;

/* methods of the character device */
static int mmap_open(struct inode *inode, struct file *filp);
static int mmap_release(struct inode *inode, struct file *filp);


/* the file operations, i.e. all character device methods */
static struct file_operations mmap_fops = {
    .open   = mmap_open,
    .release= mmap_release,
    .owner  = THIS_MODULE,
};
static int *vmalloc_area;

#define NPAGES      1//16
#define BUFF_SIZE   64 // bytes

/* character device open method */
static int mmap_open(struct inode *inode, struct file *filp)
{
    return 0;
}

/* character device last close method */
static int mmap_release(struct inode *inode, struct file *filp)
{
    return 0;
}

ssize_t read(struct file *filp, int *buff, size_t count, loff_t *offp) 
{
    unsigned long bytes_left;

    printk("Inside read \n");

    bytes_left = copy_to_user(buff, vmalloc_area , count);

    if(bytes_left<0)
    bytes_left =  -EFAULT;

    return bytes_left;
}

/* module initialization - called at module load time */
static int __init membuff_init(void)
{
    int ret = 0, i =0;

    printk(KERN_ERR "@membuff_init\n");

    /* allocate a memory area with vmalloc. */
    if ((vmalloc_area = vmalloc(BUFF_SIZE)) == NULL) {
        ret = -ENOMEM;
        goto out_vfree;
    }

    /* get the major number of the character device */
    if( (ret = alloc_chrdev_region(&mmap_dev, 0, 1, "mmap")) < 0) {
        printk(KERN_ERR "@membuff_init could not allocate major number for mmap\n");
        goto out_vfree;
    }
    printk(KERN_ERR "@membuff_init Major number for mmap: %d\n",MAJOR(mmap_dev));

    /* initialize the device structure and register the device with the kernel */
    cdev_init(&mmap_cdev, &mmap_fops);
    if ((ret = cdev_add(&mmap_cdev, mmap_dev, 1)) < 0) {
        printk(KERN_ERR "@membuff_init could not allocate chrdev for mmap\n");
        goto out_unalloc_region;
    }

    for (i = 0; i < (BUFF_SIZE / sizeof(int)); i +=1) {
    vmalloc_area[i] = i;
    printk(KERN_ERR "@membuff_init: %d\n",vmalloc_area[i]);
    }
    return ret;

    out_unalloc_region:
    unregister_chrdev_region(mmap_dev, 1);
    out_vfree:
    if(vmalloc_area)
    vfree(vmalloc_area);
    return ret;
}

/* module unload */
static void __exit mmap_exit(void)
{
if(vmalloc_area)
vfree(vmalloc_area);

/* remove the character deivce */
cdev_del(&mmap_cdev);
unregister_chrdev_region(mmap_dev, 1);

printk(KERN_ERR "@mmap_exit\n");
}

module_init(membuff_init);
module_exit(mmap_exit);
MODULE_DESCRIPTION("trying out copy_to_user");
MODULE_LICENSE("Dual BSD/GPL");

0 个答案:

没有答案