Re: character device driver reading only last character of buffer
On Sun, Sep 26, 2010 at 9:41 AM, Bond jamesbond.2...@gmail.com wrote: On Sun, Sep 26, 2010 at 3:43 AM, Venkatram Tummala venkatram...@gmail.com wrote: Hey buddy, i took the module code in your first post modified it to make it work . I am attaching the code. I am sure that it will not work the thing what I asked the question. If you are to copy only 1 byte that even my code has been doing. There is no improvement in your code. You are also giving memory_buffer = kmalloc(1, GFP_KERNEL); memset(memory_buffer, 0, 1); but since you were smart not to paste the code as I did or rather say it was my problem so I am trying to understand so no one is giving lecture to you to read what malloc is or start making programs for insertion sort. You people are free to kick me out of the list but make sure when some one asks a question you do not give them fundas give them some thing which actually works your code does not work what in what I am trying to do.
Re: character device driver reading only last character of buffer
On Sat, Sep 25, 2010 at 9:46 PM, Bond jamesbond.2...@gmail.com wrote: On Sun, Sep 26, 2010 at 3:43 AM, Venkatram Tummala venkatram...@gmail.com wrote: This will print the the last character of the string you wrote. If you would have read the thread from my first post printing the last character is not my objective I am trying to print the complete string. Yes, it is possible to pass in 0 for register_chrdev. Please be clear what you want to achieve, from your subject line the post. The subject line the first few lines of the post indicates that you need something which prints only the last character. And you go on creating a rucus around here. I have updated the code attached it. This can only read write 10 characters. Now, please dont tell us that it is not you wanted or it doesn't work. Please spare us. As a side note, please spare us all with all this non-sense. We have better things to do in our life. Please try your level best to understand things before asking the kernel mailing list. If this BS continues, i am afraid you will get yourself kicked out of the mailing list. Please do yourself a favour by not posting such crap. Venkatram Tummala Please read the thread before giving a lecture on kernel newbies. /* Necessary includes for device drivers */ #include linux/init.h //#include linux/config.h #include linux/module.h #include linux/kernel.h /* printk() */ #include linux/slab.h /* kmalloc() */ #include linux/fs.h /* everything... */ #include linux/errno.h /* error codes */ #include linux/types.h /* size_t */ #include linux/proc_fs.h #include linux/fcntl.h /* O_ACCMODE */ #include asm/system.h /* cli(), *_flags */ #include asm/uaccess.h /* copy_from/to_user */ MODULE_LICENSE(Dual BSD/GPL); /* Declaration of memory.c functions */ int memory_open(struct inode *inode, struct file *filp); int memory_release(struct inode *inode, struct file *filp); ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); ssize_t memory_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos); void memory_exit(void); int memory_init(void); /* Structure that declares the usual file */ /* access functions */ struct file_operations memory_fops = { read: memory_read, write: memory_write, open: memory_open, release: memory_release }; /* Declaration of the init and exit functions */ module_init(memory_init); module_exit(memory_exit); /* Buffer to store data */ char *memory_buffer; int result; int memory_init(void) { /* Registering device */ result = register_chrdev(0, bond, memory_fops); if (result 0) { printk(KERN_ALERT memory: cannot obtain major number \n); return result; } /* Allocating memory for the buffer */ memory_buffer = kmalloc(10, GFP_KERNEL); if (!memory_buffer) { result = -ENOMEM; goto fail; } memset(memory_buffer, 0, 10); printk(KERN_ALERT Inserting bond module\n); return 0; fail: memory_exit(); return result; } void memory_exit(void) { /* Freeing the major number */ unregister_chrdev(result, bond); /* Freeing buffer memory */ if (memory_buffer) { kfree(memory_buffer); } printk( KERN_ALERT Removing bond module\n); } int memory_open(struct inode *inode, struct file *filp) { /* Success */ return 0; } int memory_release(struct inode *inode, struct file *filp) { /* Success */ return 0; } ssize_t memory_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { if (*f_pos 0) return 0; if (count strlen(memory_buffer)) count = strlen(memory_buffer); copy_to_user(buf,memory_buffer,count); *f_pos = *f_pos + count; return count; } ssize_t memory_write( struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { copy_from_user(memory_buffer, buf, count); return count; }
Re: character device driver reading only last character of buffer
On Sun, Sep 26, 2010 at 12:10 PM, Venkatram Tummala venkatram...@gmail.comwrote: Yes, it is possible to pass in 0 for register_chrdev. Please be clear what you want to achieve, from your subject line the post. The subject line the first few lines of the post indicates that That is not my fault if you do not read the thread for one character even I was able to make it. you need something which prints only the last character. And you go on creating a rucus around here. Who is creating rucus me or people giving me non sensical lecture to read malloc they hide their incompetency by giving lecture to Google. I have updated the code attached it. This can only read write 10 characters. Now, please dont tell us that it is not you wanted or it doesn't work. Please spare us. Your code is giving me some error I did Step 1) mknod /dev/bond c 0 0 Step 2) chmod 666 /dev/bond Step 3) insmod bond.ko Step 4) r...@bond:~# lsmod | grep bond bond2031 0 Step5) echo -n abcde /dev/bond gives me error *bash: /dev/bond: No such device or address *Step 6) where* *as I can see ls -l /dev/bond* *crw-rw-rw- 1 root root 0, 0 2010-09-26 12:14 /dev/bond in your code you have done in memory_read *f_pos = *f_pos + count; why have you done this? What purpose it serves?
Re: character device driver reading only last character of buffer
On Sat, Sep 25, 2010 at 11:50 PM, Bond jamesbond.2...@gmail.com wrote: On Sun, Sep 26, 2010 at 12:10 PM, Venkatram Tummala venkatram...@gmail.com wrote: Yes, it is possible to pass in 0 for register_chrdev. Please be clear what you want to achieve, from your subject line the post. The subject line the first few lines of the post indicates that That is not my fault if you do not read the thread for one character even I was able to make it. Read my post first. And see for yourself as to who cannot make out . These were the steps I told you to do. 1) insmod MODULE.ko 2) cat /proc/devices |grep DEVICENAME This will fetch you a number. Use it in step 3 3) mknod /dev/DEVICENAME c Number from step 2 0 4) echo -n whatever /dev/DEVICENAME 5) cat /dev/DEVICENAME Are these 5 steps so difficult for you to even reproduce. I think even a 1st grader can do this better than you. you need something which prints only the last character. And you go on creating a rucus around here. Who is creating rucus me or people giving me non sensical lecture to read malloc they hide their incompetency by giving lecture to Google. I have updated the code attached it. This can only read write 10 characters. Now, please dont tell us that it is not you wanted or it doesn't work. Please spare us. Your code is giving me some error I did Step 1) mknod /dev/bond c 0 0 Why how the hell did you do this step before inserting the module. Do a cat /proc/devices|grep DEVICENAME. This will get you the number. Then do mknod /dev/bond c NUMBER in /proc/devices 0 . zero in register_chrdev(..) is not the device number. It indicates a dynamic number. Step 2) chmod 666 /dev/bond I didn't tell you to do this step. Step 3) insmod bond.ko Step 4) r...@bond:~# lsmod | grep bond bond2031 0 Step5) echo -n abcde /dev/bond gives me error *bash: /dev/bond: No such device or address *Step 6) where* *as I can see ls -l /dev/bond* *crw-rw-rw- 1 root root 0, 0 2010-09-26 12:14 /dev/bond in your code you have done in memory_read *f_pos = *f_pos + count; why have you done this? What purpose it serves? It updates the file pointer.
Re: character device driver reading only last character of buffer
On Sun, Sep 26, 2010 at 12:30 PM, Venkatram Tummala venkatram...@gmail.comwrote: Do a cat /proc/devices|grep DEVICENAME. This will get you the number. I am getting two numbers here b...@bond:~/programming/venkatrama$ cat /proc/devices | grep bond 60 bond 250 bond which one should I use. Then do mknod /dev/bond c NUMBER in /proc/devices 0 . zero in register_chrdev(..) is not the device number. It indicates a dynamic number. http://www.fsl.cs.sunysb.edu/kernel-api/re941.html how is major number then assigned. How is the name of device then decided excerpts from the above link say The name of this device has nothing to do with the name of the device in /dev. It only helps to keep track of the different owners of devices. If your module name has only one type of devices it's ok to use e.g. the name of the module here. how do I make sure that if I am writing to device /dev/bond then bond module is being used in your code you have done in memory_read *f_pos = *f_pos + count; why have you done this? What purpose it serves? It updates the file pointer. Your program has worked I used 60 in mknod out of two outputs which came in cat /proc/device | grep bond
Re: character device driver reading only last character of buffer
On Sun, Sep 26, 2010 at 12:21 AM, Bond jamesbond.2...@gmail.com wrote: On Sun, Sep 26, 2010 at 12:30 PM, Venkatram Tummala venkatram...@gmail.com wrote: in your code you have done in memory_read *f_pos = *f_pos + count; why have you done this? What purpose it serves? It updates the file pointer. Why is that important to update the pointer? Can this be not done without updating. Try writing a user space file handling program in C. I repeat what other have already said before. Before starting kernel development, you need to know the user space basics. The first read comes in with a *f_pos of 0. If you dont update the file pointer, the user space program will keep reading from f_pos 0 indefinitely. As file pointer is at offset 0 always because you dont update *f_pos, every read(..) called by user space will succeed. So, your command cat /dev/bond will never return. user space programs generally look for a specific return code to know that it is the end of the file. Your read function is ssize_t memory_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { if (*f_pos 0) return 0; if (count strlen(memory_buffer)) count = strlen(memory_buffer); copy_to_user(buf,memory_buffer,count); *f_pos = *f_pos + count; return count; } I am not able to understand why one needs to update f_pos to be able to write to userspace or when I am doing a cat /dev/bond
Re: character device driver reading only last character of buffer
On Sun, Sep 26, 2010 at 1:00 PM, Venkatram Tummala venkatram...@gmail.comwrote: Try writing a user space file handling program in C. I repeat what other have already said before. Before starting kernel development, you need to know the user space basics. I have done what you are saying in user space not once many times. Since you have been able to debug my code so I am mentioning I have made programs to insert ,delete a node in a link list ,reverse a link list,stack que implementations via link list,binary search trees, algorithms mentioned in the graphs chapter of Coreman book I have programmed, I have made socket programs which can read and write data to a socket stream (very basic network programming done) used seek,lseek methods in user space. The first read comes in with a *f_pos of 0. If you dont update the file pointer, the user space program will keep reading from f_pos 0 indefinitely. As file pointer is at offset 0 always because you dont update *f_pos, every read(..) called by user space will succeed. So, your command cat /dev/bond will never return. user space programs generally look for a specific return code to know that it is the end of the file. Thanks a lot for this one I was not clear on this part.
Re: character device driver reading only last character of buffer
On Sun, Sep 26, 2010 at 1:04 PM, Bond jamesbond.2...@gmail.com wrote: The first read comes in with a *f_pos of 0. If you dont update the file pointer, the user space program will keep reading from f_pos 0 indefinitely. As file pointer is at offset 0 always because you dont update *f_pos, every read(..) called by user space will succeed. So, your command cat /dev/bond will never return. user space programs generally look for a specific return code to know that it is the end of the file. That is the reason in strace I was getting mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2a2f03b000 write(1, abcde, 5)= 1 write(1, bcde, 4) = 1 write(1, cde, 3) = 1 write(1, de, 2) = 1 write(1, e, 1)= 1 close(1)= 0 munmap(0x7f2a2f03b000, 4096)= 0 close(2)= 0 exit_group(0) = ? What should I be reading to the thing you just mentioned in the above paragraph about updating file pointer f_pos meaniing what is happening each time when a user space call to read is done.
Re: character device driver reading only last character of buffer
On Sun, Sep 26, 2010 at 1:07 PM, Bond jamesbond.2...@gmail.com wrote: will never return. user space programs generally look for a specific return code to know that it is the end of the file. Are you referring to \0
Re: character device driver reading only last character of buffer
On Fri, Sep 24, 2010 at 10:51 PM, Mulyadi Santosa mulyadi.sant...@gmail.com wrote: When a senior member like Greg Freemyer respond like that, it must be Rather than giving me lecture here show me how this error can be fixed and let him prove if he deserves respect I do not have any problem in that,.
Re: character device driver reading only last character of buffer
On Sat, Sep 25, 2010 at 8:36 PM, ptchinster ptchins...@archlinux.us wrote: Yup. Thank you for placing where i got it, i didn't save info when i saved this source. It didn't even compiled on my machine.
Re: character device driver reading only last character of buffer
running an strace on the program gave me mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2a2f03b000 write(1, abcde, 5)= 1 write(1, bcde, 4) = 1 write(1, cde, 3) = 1 write(1, de, 2) = 1 write(1, e, 1)= 1 close(1)= 0 munmap(0x7f2a2f03b000, 4096)= 0 close(2)= 0 exit_group(0) = ? any suggestions here on the list are not working and people are giving me lectures. You people show me some real code rather than speaking non sense.
Re: character device driver reading only last character of buffer
Since you people think me to be a newbie or moron or some thing like copy pasting the code so I am explaining each and every line of it what it is doing but still lectures are lectures and funda's don't work show me real thing or else do not reply. #include linux/init.h #include linux/module.h #include linux/kernel.h /* printk() */ #include linux/slab.h /* kmalloc() */ #include linux/fs.h /* everything... */ #include linux/errno.h /* error codes */ #include linux/types.h /* size_t */ #include linux/proc_fs.h #include linux/fcntl.h /* O_ACCMODE */ #include asm/system.h /* cli(), *_flags */ #include asm/uaccess.h /* copy_from/to_user */ The section declared above is used to include header files. MODULE_LICENSE(Dual BSD/GPL); MODULE_LICENSE is an exported symbol. int bond_open(struct inode *inode, struct file *filp); int bond_release(struct inode *inode, struct file *filp); ssize_t bond_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); ssize_t bond_write(struct file *filp, char *buf, size_t count, loff_t *f_pos); just above defined four functions which will be used in structure file_operations which is of type defined in fs.h void bond_exit(void); int bond_init(void); my init and exit modules of code. struct file_operations bond_fops = { .read = bond_read, .write = bond_write, .open = bond_open, .release = bond_release declared as above as per new C99 rules so that rest of the file_operations which are not defined be declared NULL }; above operations corresponding to the system calls an application can apply to a file : file operations as in fs.h module_init(bond_init); module_exit(bond_exit); my init and exit modules int bond_major = 60; there is another way alloc_chrdrv but I am using register_chrdrv so defining the major number char *bond_buffer; device buffer to store data when user programs access it int bond_init(void) { int result; result = register_chrdev(bond_major, bond, bond_fops); if (result 0) { printk(KERN_ALERT memory: cannot obtain major number %d\n, bond_major); return result; } bond_buffer = kmalloc(14, GFP_KERNEL); giving 14 bytes to buffer three types GFP_KERNEL,GFP_ATOMIC one more I forgot if (!bond_buffer) { result = -ENOMEM; goto fail; } in case of error above will stop execution memset(bond_buffer, 0, 14); filling all the bytes of memory Claros pointed me here that if I ever used malloc function in my life so mentioning this was important for him. printk(KERN_ALERT Inserting bond module\n); return 0; fail: bond_exit(); return result; same when returns a -ve value if fail to register the major number 60 } void bond_exit(void) { unregister_chrdev(bond_major, bond); if (bond_buffer) { kfree(bond_buffer); } printk( KERN_ALERT Removing bond module\n); } just above is a clean up module when driver exits or unloads int bond_open(struct inode *inode, struct file *filp) { return 0; } will be needed when a process opens the file int bond_release(struct inode *inode, struct file *filp) { return 0; } when releasing device driver ssize_t bond_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { copy_to_user(buf,bond_buffer,count14 ? count:14); This function works as given here http://www.gnugeneration.com/mirrors/kernel-api/r4299.html and an example of this in the current kernel is linux-2.6/drivers/char/snsc.c they implemented a function scdrv_write I implemented bond_write both implementations are different do you people get that or still some lecture is missing. } ssize_t bond_write( struct file *filp, char *buf, size_t count, loff_t *f_pos) { copy_from_user(bond_buffer,buf,count14 ? count : 14); from the userspace buf copy the bytes whose total number is equal to count to bond_buffer return 1; } The above fundas and lectures do not work.You people give lectures or show attitude but only if the code works.
Re: character device driver reading only last character of buffer
On Sun, Sep 26, 2010 at 3:43 AM, Venkatram Tummala venkatram...@gmail.comwrote: Hey buddy, i took the module code in your first post modified it to make it work . I am attaching the code. It works on the latest kernel 2.6.35. If you are using any other kernel, you may have to change the file_operations function pointers (memory_read memory_write signatures) by looking at struct file_operations in include/linux/fs.h. Rest assured, the code does exactly what you want it do. I am also using 2.6.35 and it did not worked on my machine. echo -n somehing /dev/bond where as ls -l /dev/bond crw-rw-rw- 1 root root 60, 0 2010-09-26 09:32 /dev/bond exists. I see you modified the read and write functions and added __user to datatypes. more over here ssize_t memory_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { if (*f_pos != 0) return 0; copy_to_user(buf,memory_buffer,1); if(*f_pos == 0) *f_pos = *f_pos + 1; return 1; } you are always returning one byte on reading how can you say that the code will write complete thing on successful call of memory_read similarly on memory_write you are returning one byte where as I am trying to attempt to write more than one byte at one time if I give a string something it is 8 bytes so in that case memory_read will always return the number of bytes as 1 which I do not want. Since on my machine it gave me error so I am not in a position to verify what you are saying.
Re: character device driver reading only last character of buffer
On Sun, Sep 26, 2010 at 3:43 AM, Venkatram Tummala venkatram...@gmail.comwrote: This will print the the last character of the string you wrote. If you would have read the thread from my first post printing the last character is not my objective I am trying to print the complete string. As a side note, please spare us all with all this non-sense. We have better things to do in our life. Please try your level best to understand things before asking the kernel mailing list. If this BS continues, i am afraid you will get yourself kicked out of the mailing list. Please do yourself a favour by not posting such crap. Venkatram Tummala Please read the thread before giving a lecture on kernel newbies.
Re: character device driver reading only last character of buffer
Your code /* Registering device */ result = register_chrdev(0, bond, bond_fops); registers the device with major number 0.Is that possible ? On Sun, Sep 26, 2010 at 10:16 AM, Bond jamesbond.2...@gmail.com wrote: On Sun, Sep 26, 2010 at 3:43 AM, Venkatram Tummala venkatram...@gmail.com wrote: This will print the the last character of the string you wrote. If you would have read the thread from my first post printing the last character is not my objective I am trying to print the complete string. As a side note, please spare us all with all this non-sense. We have better things to do in our life. Please try your level best to understand things before asking the kernel mailing list. If this BS continues, i am afraid you will get yourself kicked out of the mailing list. Please do yourself a favour by not posting such crap. Venkatram Tummala Please read the thread before giving a lecture on kernel newbies.
Re: character device driver reading only last character of buffer
copy_from_user(memory_buffer,tmp,count10 ? count : 10); return 1; } The above also did not worked when I had posted this in the first post I have changed kmalloc and copy_from_user, copy_to_user as some of you above have suggested to have a buffer size type of thing but it also did not worked. isn't that supposed to be: copy_from_user(memory_buffer,buf,count10 ? count : 10) ? And just make sure you copy it right, e.g which pointer hold address to user space and which one toward kernel space NB: no one can stop us from asking... Bond, did you remember when I said you remind me to my younger days? I was as rude as you're...maybe more, hell lot more. And what did I getcertainly not respect...even a bit. When a senior member like Greg Freemyer respond like that, it must be something that bothered him. To the best I know, Greg is one of the best and helpful person here. His experience is certainly way way above the average ( see his posts when dealing with storage and filesystem). So, instead of replying like that...which just asking for more trouble...why not take a step or two back and think what did I do wrong?. Then open dialog. I am sure Greg is not asking for bloated respect, not at all. He just wanted you to do more on your own based on everybody cues here. PS: You feel clueless? you're not the first...and certainly won't be the last. face it, this is real world..not wonderland...nor heaven. Sometimes you need to work on your own really really hard to teach yourself. But the reward? fantastic... But should that make you rude to newbie after you? nope. You know something, you tell them...you don't know, then say sorry or just pass. If they cry like baby, let them... after a moment..they will grow up. I can guarantee that.. Hope you're not bored... -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com -- To unsubscribe from this list: send an email with unsubscribe kernelnewbies to ecar...@nl.linux.org Please read the FAQ at http://kernelnewbies.org/FAQ
character device driver reading only last character of buffer
I wrote a small hello world type of character device driver. When I type echo -n abcdef /dev/bond and do a cat /dev/bond then only last f of above input abcdef is displayed rest nothing is displayed. I asked this question earlier and some people suggested me some modifications I have done and experimented all that but I am unable to catch the error. Can some one point out the error? Here is the code /* Necessary includes for device drivers */ #include linux/init.h //#include linux/config.h #include linux/module.h #include linux/kernel.h /* printk() */ #include linux/slab.h /* kmalloc() */ #include linux/fs.h /* everything... */ #include linux/errno.h /* error codes */ #include linux/types.h /* size_t */ #include linux/proc_fs.h #include linux/fcntl.h /* O_ACCMODE */ #include asm/system.h /* cli(), *_flags */ #include asm/uaccess.h /* copy_from/to_user */ MODULE_LICENSE(Dual BSD/GPL); /* Declaration of memory.c functions */ int memory_open(struct inode *inode, struct file *filp); int memory_release(struct inode *inode, struct file *filp); ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos); void memory_exit(void); int memory_init(void); /* Structure that declares the usual file */ /* access functions */ struct file_operations memory_fops = { read: memory_read, write: memory_write, open: memory_open, release: memory_release }; /* Declaration of the init and exit functions */ module_init(memory_init); module_exit(memory_exit); /* Global variables of the driver */ /* Major number */ int memory_major = 60; /* Buffer to store data */ char *memory_buffer; int memory_init(void) { int result; /* Registering device */ result = register_chrdev(memory_major, bond, memory_fops); if (result 0) { printk(KERN_ALERT memory: cannot obtain major number %d\n, memory_major); return result; } /* Allocating memory for the buffer */ memory_buffer = kmalloc(1, GFP_KERNEL); if (!memory_buffer) { result = -ENOMEM; goto fail; } memset(memory_buffer, 0, 10); printk(KERN_ALERT Inserting bond module\n); return 0; fail: memory_exit(); return result; } void memory_exit(void) { /* Freeing the major number */ unregister_chrdev(memory_major, bond); /* Freeing buffer memory */ if (memory_buffer) { kfree(memory_buffer); } printk( KERN_ALERT Removing bond module\n); } int memory_open(struct inode *inode, struct file *filp) { /* Success */ return 0; } int memory_release(struct inode *inode, struct file *filp) { /* Success */ return 0; } ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { /* Transfering data to user space */ copy_to_user(buf,memory_buffer,10); /* Changing reading position as best suits */ if (*f_pos == 0) { *f_pos+=1; return 1; } else { return 0; } } ssize_t memory_write( struct file *filp, char *buf, size_t count, loff_t *f_pos) { char *tmp; tmp=buf+count-1; copy_from_user(memory_buffer,tmp,10); return 1; }
Re: character device driver reading only last character of buffer
On Sep 23, 2010, at 6:47 PM, Bond wrote: I wrote a small hello world type of character device driver. When I type echo -n abcdef /dev/bond and do a cat /dev/bond then only last f of above input abcdef is displayed rest nothing is displayed. I asked this question earlier and some people suggested me some modifications I have done and experimented all that but I am unable to catch the error. Can some one point out the error? Here is the code Have you ever used malloc() in user space? Man, I don't want to be rude, but what you need is to code in user space before putting your hands in kernel space. -- Carlo -- To unsubscribe from this list: send an email with unsubscribe kernelnewbies to ecar...@nl.linux.org Please read the FAQ at http://kernelnewbies.org/FAQ
Re: character device driver reading only last character of buffer
Some programming 101 feedback below: On Thu, Sep 23, 2010 at 12:47 PM, Bond jamesbond.2...@gmail.com wrote: I wrote a small hello world type of character device driver. When I type echo -n abcdef /dev/bond and do a cat /dev/bond then only last f of above input abcdef is displayed rest nothing is displayed. I asked this question earlier and some people suggested me some modifications I have done and experimented all that but I am unable to catch the error. Can some one point out the error? Here is the code /* Necessary includes for device drivers */ #include linux/init.h //#include linux/config.h #include linux/module.h #include linux/kernel.h /* printk() */ #include linux/slab.h /* kmalloc() */ #include linux/fs.h /* everything... */ #include linux/errno.h /* error codes */ #include linux/types.h /* size_t */ #include linux/proc_fs.h #include linux/fcntl.h /* O_ACCMODE */ #include asm/system.h /* cli(), *_flags */ #include asm/uaccess.h /* copy_from/to_user */ MODULE_LICENSE(Dual BSD/GPL); /* Declaration of memory.c functions */ int memory_open(struct inode *inode, struct file *filp); int memory_release(struct inode *inode, struct file *filp); ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos); void memory_exit(void); int memory_init(void); /* Structure that declares the usual file */ /* access functions */ struct file_operations memory_fops = { read: memory_read, write: memory_write, open: memory_open, release: memory_release }; /* Declaration of the init and exit functions */ module_init(memory_init); module_exit(memory_exit); /* Global variables of the driver */ /* Major number */ int memory_major = 60; /* Buffer to store data */ char *memory_buffer; int memory_init(void) { int result; /* Registering device */ result = register_chrdev(memory_major, bond, memory_fops); if (result 0) { printk(KERN_ALERT memory: cannot obtain major number %d\n, memory_major); return result; } /* Allocating memory for the buffer */ memory_buffer = kmalloc(1, GFP_KERNEL); 1 is the number of bytes your allocating, it needs to be your max buffer length. So are by design writing a buffer overflow the way you have it. That is one of the typical security failures that can allow a major breach. Change it to: #define MY_BUFFER_SIZE memory_buffer = kmalloc(MY_BUFFER_SIZE, GFP_KERNEL); if (!memory_buffer) { result = -ENOMEM; goto fail; } memset(memory_buffer, 0, 10); Never hard code a length. At least use a define. This becomes memset(memory_buffer, 0, MY_BUFFER_SIZE); printk(KERN_ALERT Inserting bond module\n); return 0; fail: memory_exit(); return result; } void memory_exit(void) { /* Freeing the major number */ unregister_chrdev(memory_major, bond); /* Freeing buffer memory */ if (memory_buffer) { kfree(memory_buffer); } printk( KERN_ALERT Removing bond module\n); } int memory_open(struct inode *inode, struct file *filp) { /* Success */ return 0; } int memory_release(struct inode *inode, struct file *filp) { /* Success */ return 0; } ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { /* Transfering data to user space */ copy_to_user(buf,memory_buffer,10); again, don't have 10 hardcoded, but the read should actually work as is except if the userspace buffer is too small, then your going to overflow it with untold damage. You need: copy_to_user(buf,memory_buffer,min(count, MY_BUFFER_SIZE)); /* Changing reading position as best suits */ if (*f_pos == 0) { *f_pos+=1; return 1; } else { return 0; } Since you don't use f_pos, I have no idea why you're don this. Future plans I assume. While troubleshooting I'm surprised you didn't comment this out. I would often just wrap it in a #ifdef until you get the basics working. } ssize_t memory_write( struct file *filp, char *buf, size_t count, loff_t *f_pos) { char *tmp; tmp=buf+count-1; tmp now points at the last char in buf. Clearly not what you want. I can't even think of a logical explanation for what you're trying to do. I'd just delete tmp and its assignment. Those 2 lines offer no value I see. copy_from_user(memory_buffer,tmp,10); Try this instead copy_from_user(memory_buffer, buf, min(count, MY_BUFFER_SIZE)); return 1; } It looks like you're just randomly cutting and pasting code from various places and have no idea what it really does. I'm putting you in my autodelete list, so I won't be responding to you again. Greg -- To unsubscribe from this list: send an email with unsubscribe kernelnewbies to ecar...@nl.linux.org Please read the FAQ at http://kernelnewbies.org/FAQ
Re: character device driver reading only last character of buffer
On Thu, Sep 23, 2010 at 11:47 PM, Carlo Caione carlo.cai...@gmail.com wrote: Have you ever used malloc() in user space? Man, I don't want to be rude, but what you need is to code in user space before putting your hands in kernel space. Since you mentioned so I am posting a program this uses malloc.You can see it,I have myself checked and it is working. You do show the attitude but it would be good if you show some attitude on the code I posted. #include stdio.h #include stdlib.h struct node { struct node *next, *prev; int data; } *start, *prv; void add_element(int e); void read_list (); static int j = 0; int main() { int i, element, choice; choice = 1; struct node *temp; start = NULL; while (choice == 1) { printf(What do you want 0 exit 1 to add\n); scanf(%d, choice); if (choice == 0) break; printf(Enter data to be entered\n); scanf(%d, element); add_element(element); } read_list(); } void add_element(int e) { // printf(\n printing from function %d\n, e); struct node *temp; if (j == 0) { start = (struct node *)malloc(sizeof(struct node)); start-data = e; //printf(the data entered is %d \n, start-data); prv=start;//is necessary since in otherwise case prv is pointing to some garbage value } if(j!=0){ temp = (struct node *)malloc(sizeof(struct node)); temp-data = e; prv-next = temp; temp-next=NULL; prv=temp;//since prv is global pointer if I do not do this step then next time when new memory is allocated prv is still pointing to start or previous pointer what ever the value was so new temp declaration will not have much effect } j++; } void read_list() { struct node *temp; temp = start; while (temp) { printf( %d -- , temp-data); temp = temp-next; } } On Thu, Sep 23, 2010 at 11:58 PM, Manish Katiyar mkati...@gmail.com wrote: Did you really want to allocate 1 byte ? if (!memory_buffer) { result = -ENOMEM; goto fail; } memset(memory_buffer, 0, 10); And then write 10 bytes on it without expecting to cause corruptions ? I had made that change that you said but it had not worked. On Fri, Sep 24, 2010 at 12:19 AM, Greg Freemyer greg.freem...@gmail.com wrote: I'm putting you in my autodelete list, so I won't be responding to you again. You are free to put where ever you want but it would be good if you show your attitude on code not on me. This is a newbie list and no one can stop us from asking if we are in problem there are much better people here than you. On Fri, Sep 24, 2010 at 12:34 AM, Bond jamesbond.2...@gmail.com wrote: I changed that part /* Necessary includes for device drivers */ #include linux/init.h //#include linux/config.h #include linux/module.h #include linux/kernel.h /* printk() */ #include linux/slab.h /* kmalloc() */ #include linux/fs.h /* everything... */ #include linux/errno.h /* error codes */ #include linux/types.h /* size_t */ #include linux/proc_fs.h #include linux/fcntl.h /* O_ACCMODE */ #include asm/system.h /* cli(), *_flags */ #include asm/uaccess.h /* copy_from/to_user */ MODULE_LICENSE(Dual BSD/GPL); /* Declaration of memory.c functions */ int memory_open(struct inode *inode, struct file *filp); int memory_release(struct inode *inode, struct file *filp); ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos); void memory_exit(void); int memory_init(void); /* Structure that declares the usual file */ /* access functions */ struct file_operations memory_fops = { read: memory_read, write: memory_write, open: memory_open, release: memory_release }; /* Declaration of the init and exit functions */ module_init(memory_init); module_exit(memory_exit); /* Global variables of the driver */ /* Major number */ int memory_major = 60; /* Buffer to store data */ char *memory_buffer; int memory_init(void) { int result; /* Registering device */ result = register_chrdev(memory_major, bond, memory_fops); if (result 0) { printk(KERN_ALERT memory: cannot obtain major number %d\n, memory_major); return result; } /* Allocating memory for the buffer */ memory_buffer = kmalloc(10, GFP_KERNEL); if (!memory_buffer) { result = -ENOMEM; goto fail; } memset(memory_buffer, 0, 10); printk(KERN_ALERT Inserting bond module\n); return 0; fail: memory_exit(); return result; } void memory_exit(void) { /* Freeing the major number */ unregister_chrdev(memory_major, bond); /* Freeing buffer memory */ if (memory_buffer) { kfree(memory_buffer); } printk( KERN_ALERT Removing bond module\n); } int memory_open(struct inode *inode, struct file *filp) { /* Success
Re: character device driver reading only last character of buffer
I changed that part /* Necessary includes for device drivers */ #include linux/init.h //#include linux/config.h #include linux/module.h #include linux/kernel.h /* printk() */ #include linux/slab.h /* kmalloc() */ #include linux/fs.h /* everything... */ #include linux/errno.h /* error codes */ #include linux/types.h /* size_t */ #include linux/proc_fs.h #include linux/fcntl.h /* O_ACCMODE */ #include asm/system.h /* cli(), *_flags */ #include asm/uaccess.h /* copy_from/to_user */ MODULE_LICENSE(Dual BSD/GPL); /* Declaration of memory.c functions */ int memory_open(struct inode *inode, struct file *filp); int memory_release(struct inode *inode, struct file *filp); ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos); void memory_exit(void); int memory_init(void); /* Structure that declares the usual file */ /* access functions */ struct file_operations memory_fops = { read: memory_read, write: memory_write, open: memory_open, release: memory_release }; /* Declaration of the init and exit functions */ module_init(memory_init); module_exit(memory_exit); /* Global variables of the driver */ /* Major number */ int memory_major = 60; /* Buffer to store data */ char *memory_buffer; int memory_init(void) { int result; /* Registering device */ result = register_chrdev(memory_major, bond, memory_fops); if (result 0) { printk(KERN_ALERT memory: cannot obtain major number %d\n, memory_major); return result; } /* Allocating memory for the buffer */ memory_buffer = kmalloc(10, GFP_KERNEL); if (!memory_buffer) { result = -ENOMEM; goto fail; } memset(memory_buffer, 0, 10); printk(KERN_ALERT Inserting bond module\n); return 0; fail: memory_exit(); return result; } void memory_exit(void) { /* Freeing the major number */ unregister_chrdev(memory_major, bond); /* Freeing buffer memory */ if (memory_buffer) { kfree(memory_buffer); } printk( KERN_ALERT Removing bond module\n); } int memory_open(struct inode *inode, struct file *filp) { /* Success */ return 0; } int memory_release(struct inode *inode, struct file *filp) { /* Success */ return 0; } ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { /* Transfering data to user space */ copy_to_user(buf,memory_buffer,count10 ? count:10); /* Changing reading position as best suits */ /* if (*f_pos == 0) { *f_pos+=1; return 1; } else { return 0; }*/ } ssize_t memory_write( struct file *filp, char *buf, size_t count, loff_t *f_pos) { char *tmp; copy_from_user(memory_buffer,tmp,count10 ? count : 10); return 1; } The above also did not worked when I had posted this in the first post I have changed kmalloc and copy_from_user, copy_to_user as some of you above have suggested to have a buffer size type of thing but it also did not worked.
Re: character device driver reading only last character of buffer
On Fri, Sep 24, 2010 at 12:19 AM, Greg Freemyer greg.freem...@gmail.com wrote: I'm putting you in my autodelete list, so I won't be responding to you again. You are free to put where ever you want but it would be good if you show your attitude on code not on me. This is a newbie list and no one can stop us from asking if we are in problem there are much better people here than you. Kernel newbie != Programming newbie Example: I have 12 years c programming experience and about 4 years working on kernel specific c. I do not consider myself a Progamming Newbie, but I am still a Kernel Newbie. A good one step back is to work on systems programming and learn how the user space interacts with the kernel. Once, you have mastered this work you way into the kernel space. -- To unsubscribe from this list: send an email with unsubscribe kernelnewbies to ecar...@nl.linux.org Please read the FAQ at http://kernelnewbies.org/FAQ