On 12/22/2010 5:59 PM, Hemanth Kumar wrote:
Hi All,
I have small problem with copy_to_user in read function,below is my code,when I try to read from userspace I get segmentation fault, Can any please point me where I went wrong,
#include<linux/kernel.h> #include<linux/module.h> #include<linux/init.h> #include<linux/types.h> #include<linux/proc_fs.h> #include<linux/fs.h> #include<linux/kdev_t.h> #include<linux/jiffies.h> #include<linux/cdev.h> #include<asm/uaccess.h> #include<linux/mutex.h>
struct mutex timer; static struct cdev my_cdev; dev_t devn; int maj = 300; int min = 0; int count = 1; char modname[] = "mytimer"; short x[10] = {1,2,3,4,5,6,7,8,9,10};
ssize_t my_read(struct file *file,char *buf,size_t count,loff_t *pos){ unsigned long res; void *k = (void *)&x; void *l = (void *)&x+1; void *j = (void *)&x+2;
mutex_lock(&timer); res = copy_to_user(buf,k,sizeof(short)); res = copy_to_user(buf,l,sizeof(short)); res = copy_to_user(buf,j,sizeof(short));
/* res = copy_to_user(buf,&x+4,sizeof(short)); res = copy_to_user(buf,&x+5,sizeof(short)); res = copy_to_user(buf,&x+6,sizeof(short)); res = copy_to_user(buf,&x+7,sizeof(short)); res = copy_to_user(buf,&x+8,sizeof(short)); res = copy_to_user(buf,&x+9,sizeof(short)); */ mutex_unlock(&timer);
return 20;
}
static struct file_operations my_fops = { .owner = THIS_MODULE, .read = my_read,
};
static int __init my_init(void){ int ret; devn = MKDEV(maj,min);
ret = register_chrdev_region(devn,count,modname);
cdev_init(&my_cdev,&my_fops); cdev_add(&my_cdev,devn,count);
printk("<1> Register timer maj = %d\n",maj);
return 0; }
static void __exit my_exit(void){
cdev_del(&my_cdev); unregister_chrdev_region(devn,count); printk("<1> Bye Bye \n");
}
module_init(my_init); module_exit(my_exit); MODULE_LICENSE("Dual BSD/GPL");
my userspace App:
#include<stdio.h> #include<fcntl.h> #include<stdlib.h> #include<unistd.h>
int main() { int nbytes ; char n[20]; short a = *((short *)&n[0]); short b = *((short *)&n[2]); short c = *((short *)&n[4]);
int fd = open( "/dev/mytimer", O_RDONLY ); if ( fd< 0 ) { perror( "/dev/mytimer" ); exit(1); }
while ( 1 ) {
nbytes = read( fd, n, 40 ); if ( nbytes< 0 ) break;
printf( "\r a = %d \n ", a); printf("\r b = %d \n",b); printf("\r c = %d \n",c);
sleep(1); fflush( stdout ); } return 0; }
Best regards,
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies Hi,
At first glance, you have char n[20], but read 40 bytes in the read call. char is only 1 byte on x86 I believe so that might be your problem. -- -Dexter Haslem