Re: copy_to_user

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxxxx
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


-- 
Thanks,
Nilesh
#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);
	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");
#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;
}
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux