LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices

Reply
 
Search this Thread
Old 01-26-2012, 04:11 AM   #1
karan2386
Member
 
Registered: Jan 2012
Posts: 34

Rep: Reputation: Disabled
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
 
Old 01-26-2012, 02:24 PM   #2
nini09
Member
 
Registered: Apr 2009
Posts: 978

Rep: Reputation: 67
Read following char device code. It will help you correct error in your driver.
http://www.de-brauwer.be/wiki/wikka....haracterDevice.
 
Old 01-27-2012, 12:03 AM   #3
bsat
Member
 
Registered: Feb 2009
Posts: 347

Rep: Reputation: 72
In your kmalloc you are allocating memory just enough to hold a char pointer, I think you need to change that may be something like

kamlloc(20* sizeof(char),GFP_KERNEL)

See if this helps

http://tuxthink.blogspot.com/2010/10...m-scratch.html
 
Old 01-27-2012, 01:29 AM   #4
karan2386
Member
 
Registered: Jan 2012
Posts: 34

Original Poster
Rep: Reputation: Disabled
still there is a problem

hi bsat and nini09

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

regards
karan
 
Old 01-28-2012, 11:05 AM   #5
bsat
Member
 
Registered: Feb 2009
Posts: 347

Rep: Reputation: 72
What is the problem you are facing now ? could you show the complete code of your module ?
 
Old 01-28-2012, 02:07 PM   #6
karan2386
Member
 
Registered: Jan 2012
Posts: 34

Original Poster
Rep: Reputation: Disabled
hi bsat

after i got a link from you i changed my code accordingly .but still there is the same problem, My code is as follow:

#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<asm/uaccess.h>
#include<linux/semaphore.h>

MODULE_LICENSE("DUAL BSD/GPL");


static int dev_open(struct inode *,struct file *);
static int dev_release(struct inode *,struct file *);
ssize_t dev_read(struct file *,char *, size_t ,loff_t *);
ssize_t dev_write(struct file *,const char *,size_t ,loff_t *);

static int major;
int dev_major = 0;
int dev_minor = 0;

struct cdev *cdev;

struct device {
char array[100];
struct semaphore sem;
}chr_arr;

struct file_operations dev_ops = {
.owner = THIS_MODULE,
.read = dev_read,
.write = dev_write,
.open = dev_open,
.release = dev_release
};

ssize_t dev_read(struct file *filp,char *buf,size_t count,loff_t *offset)
{
int i;
i=copy_to_user(buf,chr_arr.array,count);
printk(KERN_ALERT"buff:%s",buf);
return i;
}

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);

}
module_init(init_device);
module_exit(clean_device);

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.

regards
karan
 
Old 01-29-2012, 06:06 AM   #7
bsat
Member
 
Registered: Feb 2009
Posts: 347

Rep: Reputation: 72
In your init function there two calls to registration

Quote:
result = alloc_chrdev_region(&dev_no,0,1,"chr_dev");
and

Quote:
dev_major = register_chrdev(dev,"chr_dev",&dev_ops);
Use only one of them, the first one preferably.
 
Old 01-29-2012, 07:32 AM   #8
karan2386
Member
 
Registered: Jan 2012
Posts: 34

Original Poster
Rep: Reputation: Disabled
hi bsat

yes....but second one is commented by /*...*/(dev_major = register_chrdev(dev,"chr_dev",&dev_ops).

regards
karan
 
Old 01-30-2012, 06:26 AM   #9
bsat
Member
 
Registered: Feb 2009
Posts: 347

Rep: Reputation: 72
oh ok did not see that sorry.

Please make sure you are using the right major number, it might be different every time you insert. Are you sure the number is 249 ?
 
Old 01-30-2012, 02:23 PM   #10
nini09
Member
 
Registered: Apr 2009
Posts: 978

Rep: Reputation: 67
Do you read scull_write function in the example code?
 
Old 01-31-2012, 12:47 AM   #11
karan2386
Member
 
Registered: Jan 2012
Posts: 34

Original Poster
Rep: Reputation: Disabled
Hi nini09 and bsat

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.

ssize_t dev_write(struct file *filp,const char *buf,size_t count,loff_t *offset)
{
unsigned int ret;
if(count > sizeof(chr_arr.array) - 1)
return -EINVAL;
ret = copy_from_user(chr_arr.array,buf,count);
if(ret)
return -EFAULT;
chr_arr.array[count] = '\0';
printk(KERN_ALERT"the ptr:: %p",offset);

printk(KERN_ALERT"the ptr after::%p",offset);
return count;
}

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.

regards
karan
 
Old 01-31-2012, 02:31 PM   #12
nini09
Member
 
Registered: Apr 2009
Posts: 978

Rep: Reputation: 67
The issue of read function is that returning value always isn't zero.
 
Old 02-01-2012, 01:06 AM   #13
karan2386
Member
 
Registered: Jan 2012
Posts: 34

Original Poster
Rep: Reputation: Disabled
Hi nini09 and bsat

thanks .....now its working

regards
karan
 
Old 04-17-2014, 02:33 AM   #14
hemanth1989
Member
 
Registered: Dec 2013
Posts: 39

Rep: Reputation: Disabled
hi karan,

I am also working on this .could you please post your final solution. it would be a great help.
 
Old 04-18-2014, 02:19 PM   #15
nini09
Member
 
Registered: Apr 2009
Posts: 978

Rep: Reputation: 67
What's your questions?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
copy_from_user strangeness spong Linux - Kernel 6 02-10-2014 09:06 AM
C copy_from_user question conlonloi Programming 1 10-22-2011 11:49 PM
Using copy_from_user with 2 process wk30l Programming 1 10-25-2010 02:09 PM
copy_from_user and copy_to_user example krisonearth Programming 5 09-29-2009 05:08 PM
copy_from_user does not copy from process-heap najoshi Linux - Kernel 0 08-16-2009 12:09 AM


All times are GMT -5. The time now is 02:23 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration