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,
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
--- On Thu, 23/12/10, Dexter Haslem <dexter.haslem@gmail.com> wrote:
From: Dexter Haslem <dexter.haslem@gmail.com> Subject: Re: copy_to_user To: "Hemanth Kumar" <hemwire@yahoo.co.in> Cc: Kernelnewbies@kernelnewbies.org Date: Thursday, 23 December, 2010, 6:48 AM 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.
Hi Dexter, I have commented remaining copy_to_user read function , it should be 6bytes,
-- -Dexter Haslem
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,
I guess, you need to also implement open method in your driver. Because, you are opening the device in your application. Could you try this? Regards, Srinivas G
#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
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
--- On Thu, 23/12/10, Srinivas G. <srinivasg@esntechnologies.co.in> wrote:
From: Srinivas G. <srinivasg@esntechnologies.co.in> Subject: RE: copy_to_user To: "Dexter Haslem" <dexter.haslem@gmail.com>, "Hemanth Kumar" <hemwire@yahoo.co.in> Cc: Kernelnewbies@kernelnewbies.org Date: Thursday, 23 December, 2010, 10:05 AM
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,
I guess, you need to also implement open method in your driver. Because, you are opening the device in your application. Could you try this?
Regards, Srinivas G
Hi Srinivas, I tried it,but with out any success,the same problem, regards,
#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
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On Thu, Dec 23, 2010 at 10:05 AM, Srinivas G. < srinivasg@esntechnologies.co.in> wrote:
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,
I guess, you need to also implement open method in your driver. Because, you are opening the device in your application. Could you try this?
Regards, Srinivas G
#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,
The mutex initialization is missing. Adding mutex_init(&timer); in the driver init will make it work. Thanks, Mukti
--- On Thu, 23/12/10, mukti jain <muktijn@gmail.com> wrote: From: mukti jain <muktijn@gmail.com> Subject: Re: copy_to_user To: "Srinivas G." <srinivasg@esntechnologies.co.in> Cc: "Dexter Haslem" <dexter.haslem@gmail.com>, "Hemanth Kumar" <hemwire@yahoo.co.in>, Kernelnewbies@kernelnewbies.org Date: Thursday, 23 December, 2010, 11:07 AM On Thu, Dec 23, 2010 at 10:05 AM, Srinivas G. <srinivasg@esntechnologies.co.in> wrote:
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,
I guess, you need to also implement open method in your driver. Because, you are opening the device in your application. Could you try this? Regards, Srinivas G
#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,
The mutex initialization is missing. Adding mutex_init(&timer); in the driver init will make it work.
Thanks, Mukti Hi All, still have dont have success,Can any please share some idea, Regards,
--- On Thu, 23/12/10, mukti jain <muktijn@gmail.com> wrote: From: mukti jain <muktijn@gmail.com> Subject: Re: copy_to_user To: "Srinivas G." <srinivasg@esntechnologies.co.in> Cc: "Dexter Haslem" <dexter.haslem@gmail.com>, "Hemanth Kumar" <hemwire@yahoo.co.in>, Kernelnewbies@kernelnewbies.org Date: Thursday, 23 December, 2010, 11:07 AM On Thu, Dec 23, 2010 at 10:05 AM, Srinivas G. <srinivasg@esntechnologies.co.in> wrote:
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,
I guess, you need to also implement open method in your driver. Because, you are opening the device in your application. Could you try this? Regards, Srinivas G
#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,
The mutex initialization is missing. Adding mutex_init(&timer); in the driver init will make it work.
Thanks, Mukti Hi All, Can anybody please share some idea ,why I am getting segmentation fault & kernel oops, Regards,
Hi, On Fri, 2010-12-24 at 11:37 +0530, Hemanth Kumar wrote:
> >
The mutex initialization is missing. Adding mutex_init(&timer); in the driver init will make it work.
Thanks, Mukti
Hi All,
Can anybody please share some idea ,why I am getting segmentation fault & kernel oops,
Regards,
I tried it, and it seems adding mutex_init() works as Mukti mentioned. I did get a kernel oops before (but no segfault). After adding mutex_init() there is no oops/segfault. The code, however, is reading the garbage, that needs to be fixed. pun-nilesht-dt0:/home/nilesh/Documents/handson # !mknod mknod /dev/mytimer c 300 0 pun-nilesht-dt0:/home/nilesh/Documents # dmesg [ 2193.684735] Register timer maj = 300 pun-nilesht-dt0:/home/nilesh/Documents/handson # ./my_app.o a = -30048 b = -23975 c = 32582 ... See the attachments in case something is missing the code.
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-- Thanks, Nilesh
Hi Nilesh. On Thu, Dec 23, 2010 at 11:59 PM, Nilesh Tayade <nilesh.tayade@netscout.com> wrote: ...snip...
I tried it, and it seems adding mutex_init() works as Mukti mentioned. I did get a kernel oops before (but no segfault). After adding mutex_init() there is no oops/segfault. The code, however, is reading the garbage, that needs to be fixed.
char n[20]; short a = *((short *)&n[0]); short b = *((short *)&n[2]); short c = *((short *)&n[4]); This sets a b and c to have essentially random values. nbytes = read( fd, n, 40); This causes the value of n to change. However, the values of a, b, and c retain the same random values you assigned them above. printf( "\r a = %d \n ", a); printf("\r b = %d \n",b); printf("\r c = %d \n",c); This prints the random values of a, b, and c rather than printing thee values of n that you read in. Dave Hylands
On Fri, 2010-12-24 at 01:00 -0800, Dave Hylands wrote:
Hi Nilesh.
On Thu, Dec 23, 2010 at 11:59 PM, Nilesh Tayade <nilesh.tayade@netscout.com> wrote: ...snip...
I tried it, and it seems adding mutex_init() works as Mukti mentioned. I did get a kernel oops before (but no segfault). After adding mutex_init() there is no oops/segfault. The code, however, is reading the garbage, that needs to be fixed.
char n[20]; short a = *((short *)&n[0]); short b = *((short *)&n[2]); short c = *((short *)&n[4]);
This sets a b and c to have essentially random values.
nbytes = read( fd, n, 40);
This causes the value of n to change. However, the values of a, b, and c retain the same random values you assigned them above.
printf( "\r a = %d \n ", a); printf("\r b = %d \n",b); printf("\r c = %d \n",c);
This prints the random values of a, b, and c rather than printing thee values of n that you read in.
Thanks for the explanation Dave. I did not really bother to debug to avoid the garbage values, as the main concern was for segfault and kernel oops.
Dave Hylands
-- Thanks, Nilesh
Hi Dave & Nilesh, Thanks for your support I fixed it, Regards, hemanth --- On Fri, 24/12/10, Nilesh Tayade <nilesh.tayade@netscout.com> wrote:
From: Nilesh Tayade <nilesh.tayade@netscout.com> Subject: Re: copy_to_user To: "Dave Hylands" <dhylands@gmail.com> Cc: "Srinivas G." <srinivasg@esntechnologies.co.in>, "Dexter Haslem" <dexter.haslem@gmail.com>, "Hemanth Kumar" <hemwire@yahoo.co.in>, "mukti jain" <muktijn@gmail.com>, Kernelnewbies@kernelnewbies.org Date: Friday, 24 December, 2010, 2:50 PM On Fri, 2010-12-24 at 01:00 -0800, Dave Hylands wrote:
Hi Nilesh.
On Thu, Dec 23, 2010 at 11:59 PM, Nilesh Tayade <nilesh.tayade@netscout.com> wrote: ...snip...
I tried it, and it seems adding mutex_init() works as Mukti mentioned. I did get a kernel oops before (but no segfault). After adding mutex_init() there is no oops/segfault. The code, however, is reading the garbage, that needs to be fixed.
char n[20]; short a = *((short *)&n[0]); short b = *((short *)&n[2]); short c = *((short *)&n[4]);
This sets a b and c to have essentially random values.
nbytes = read( fd, n, 40);
This causes the value of n to change. However, the values of a, b, and c retain the same random values you assigned them above.
printf( "\r a = %d \n ", a); printf("\r b = %d \n",b); printf("\r c = %d \n",c);
This prints the random values of a, b, and c rather than printing thee values of n that you read in.
Thanks for the explanation Dave.
I did not really bother to debug to avoid the garbage values, as the main concern was for segfault and kernel oops.
Dave Hylands
-- Thanks, Nilesh
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Hi Nilesh & mukti, --- On Fri, 24/12/10, Nilesh Tayade <nilesh.tayade@netscout.com> wrote:
From: Nilesh Tayade <nilesh.tayade@netscout.com> Subject: Re: copy_to_user To: "Hemanth Kumar" <hemwire@yahoo.co.in> Cc: "Dexter Haslem" <dexter.haslem@gmail.com>, "mukti jain" <muktijn@gmail.com>, "Srinivas G." <srinivasg@esntechnologies.co.in>, Kernelnewbies@kernelnewbies.org Date: Friday, 24 December, 2010, 1:29 PM Hi,
On Fri, 2010-12-24 at 11:37 +0530, Hemanth Kumar wrote:
> >
The mutex initialization is missing. Adding mutex_init(&timer); in the driver init will make it work. Thanks, Mukti Hi All,
Can anybody please share some idea ,why I am getting
segmentation fault & kernel oops, Regards,
I tried it, and it seems adding mutex_init() works as Mukti mentioned. I did get a kernel oops before (but no segfault). After adding mutex_init() there is no oops/segfault. The code, however, is reading the garbage, that needs to be fixed.
pun-nilesht-dt0:/home/nilesh/Documents/handson # !mknod mknod /dev/mytimer c 300 0
pun-nilesht-dt0:/home/nilesh/Documents # dmesg [ 2193.684735] Register timer maj = 300
pun-nilesht-dt0:/home/nilesh/Documents/handson # ./my_app.o
a = -30048 b = -23975 c = 32582 ...
See the attachments in case something is missing the code.
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-- Thanks, Nilesh
-----Inline Attachment Follows-----
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
I tried to do that,But it is reading the last element in the array(x[2] = 43), I have modified a bit but still not able read for x[0],below is the code, #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,43,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_unlock(&timer); return 6; } 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); mutex_init(&timer); printk(KERN_CRIT "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"); user space app #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> int main() { int nbytes ; char n[20]; int fd = open( "/dev/mytimer", O_RDONLY ); if ( fd < 0 ) { perror( "/dev/mytimer" ); exit(1); } while ( 1 ) { nbytes = read( fd, n, 20); if ( nbytes < 0 ) break; short a = *((short *)&n[0]); short b = *((short *)&n[2]); short c = *((short *)&n[4]); printf( "\r a = %d \n ", a); printf("\r b = %d \n",b); printf("\r c = %d \n",c); sleep(1); fflush( stdout ); } return 0; } [root@Praval userspace]# ./my_app a = 43 b = 0 c = -26552 a = 43 b = 0 c = -26552 a = 43 b = 0 c = -26552 a = 43 b = 0 c = -26552 a = 43 b = 0 c = -26552 I think i still miss something,
participants (6)
-
Dave Hylands -
Dexter Haslem -
Hemanth Kumar -
mukti jain -
Nilesh Tayade -
Srinivas G.