On Sat, Sep 25, 2010 at 8:34 AM, Bond <jamesbond.2...@gmail.com> wrote:
> 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,count<14 ? 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,count<14 ? 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. > 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. Do the following steps : 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> This will print the the last character of the string you wrote. 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
/* 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(1, GFP_KERNEL); if (!memory_buffer) { result = -ENOMEM; goto fail; } memset(memory_buffer, 0, 1); 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; copy_to_user(buf,memory_buffer,1); if(*f_pos == 0) *f_pos = *f_pos + 1; return 1; } 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 - 1, 1); return 1; }