[SOLVED] how to write on a device file using copy_from_user()
Linux - KernelThis forum is for all discussion relating to the Linux kernel.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
how to write on a device file using copy_from_user()
Hi ,
I am new to linux and was making a module in which user can read as well as write to a device file.the following is my code where read is working fine but not the write function.
Code:
MODULE_LICENSE("DUAL BSD/GPL");
char message[80];
char *msg_ptr;
int dev_major = 0;
int dev_minor = 0;
struct cdev *cdev;
ssize_t dev_read(struct file *filp,char __user *buf,size_t count,loff_t *offset)
{
int i;
i=copy_to_user(buf,msg_ptr,count);
printk(KERN_ALERT"buff:%s",buf);
if(buf == '\0')
{
printk("you idiot dont show your face again");
return 0;
}
return 0;
}
ssize_t dev_write(struct file *filp,const char __user *buf,size_t count,loff_t *offset)
{
int j;
msg_ptr = kmalloc(sizeof(*buf),GFP_KERNEL);
//for(j=0;j<count;j++)
copy_from_user(msg_ptr,buf,sizeof(*buf));
//printk(KERN_ALERT"msg_ptr:%s",msg_ptr);
return 0;
}
when i make a char node and then use echo hi >/dev/my_dev then it prints hi but writes infintely as seen in /var/log/messages . Please help.reply as soon as possible.
regards
karan
Last edited by colucix; 01-26-2012 at 08:19 AM.
Reason: Added CODE tags to improve readability
hi have gone through your links and had made changes like kamlloc(20* sizeof(char),GFP_KERNEL) and copy_from_user(msg_ptr,buf,count). but still theer is the same problem . could please reply any more suggestions
ssize_t dev_write(struct file *filp,const char *buf,size_t count,loff_t *offset)
{
//printk(KERN_ALERT"\nsorry,byebye");
int j;
//msg_ptr = kmalloc(count,GFP_KERNEL);
//for(j=0;j<count;j++)
if(count>100)
return -1;
j = copy_from_user(chr_arr.array,buf,count);
//printk(KERN_ALERT"msg_ptr:%s",msg_ptr);
return j;
}
static int dev_open(struct inode *inode,struct file *filp)
{
filp->private_data = inode->i_cdev;
if(down_interruptible(&chr_arr.sem))
{
printk(KERN_INFO " could not hold semaphore");
return -1;
}
//printk(KERN_ALERT"ah ha the device is open !now we can go further");
return 0;
}
static int dev_release(struct inode *inode,struct file *filp)
{
up(&chr_arr.sem);
return 0;
//module_put(THIS_MODULE);
return 0;
}
static int init_device(void)
{
int result;
dev_t dev_no,dev;
result = alloc_chrdev_region(&dev_no,0,1,"chr_dev");
if(result < 0)
{
printk("sorry no major number left");
return result;
}
major = MAJOR(dev_no);
dev = MKDEV(major,0);
cdev = cdev_alloc();
cdev->ops = &dev_ops;
sema_init(&chr_arr.sem,1);
printk("the major number allocated is %d\n",major);
result = cdev_add(cdev,dev,1);
if(result < 0 )
{
printk(KERN_INFO "Unable to allocate cdev");
return result;
}
/*dev_t dev =0;
dev_major = register_chrdev(dev,"chr_dev",&dev_ops);
printk(KERN_ALERT"MAJOR NUMBER IS:%d and minor is:%d",dev_major,dev_minor);*/
return 0;
}
static void clean_device(void)
{
//dev_t devno = MKDEV(dev_major, dev_minor);
//printk(KERN_ALERT"removing MAJOR NUMBER IS:%d and removing minor is:%d",dev_major,dev_minor);
cdev_del(cdev);
unregister_chrdev_region(major,1);
and then when i do insmod rwd.ko, mknod /dev/chr_dev c 249 0 , echo hi > /dev/chr_dev the screen hangs after few seconds. Really thanks for your intrest.
I have following the book ldd (and i think this example is taken from there). its bit complex. i just wanted to see how we can use copy_to_user and copy_from_user for reading and writing . I have solved my problem of writing function as now i am return count and putting last bit to null in array. it is as follow what i have done.
but now the problem lies in read function now whenever i try to cat /dev/my_dev it runs for infintely.further for bsat, i have checked the major numbers from /var/log/messages and its not a problem. further any help would be great.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.