On Sat, Sep 25, 2010 at 7:34 PM, Bond <[email protected]> wrote:
> > > On Fri, Sep 24, 2010 at 5:41 PM, sri <[email protected]> wrote: > >> what part is not able to understand? >> >> Here is a program I wrote > but it is dropping characters though I gave 14 bytes to kmalloc and buffer > but still the program is unable to read and write as I expect it to do. > I did an strace on the program and have posted the log at the end > > > #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 */ > > MODULE_LICENSE("Dual BSD/GPL"); > > > 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); > void bond_exit(void); > int bond_init(void); > > struct file_operations bond_fops = { > read: bond_read, > write: bond_write, > open: bond_open, > release: bond_release > }; > > module_init(bond_init); > module_exit(bond_exit); > > int bond_major = 60; > > char *bond_buffer; > > 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); > if (!bond_buffer) { > result = -ENOMEM; > goto fail; > } > memset(bond_buffer, 0, 14); > > printk(KERN_ALERT "Inserting bond module\n"); > return 0; > > fail: > bond_exit(); > return result; > } > > > void bond_exit(void) { > > unregister_chrdev(bond_major, "bond"); > > > if (bond_buffer) { > kfree(bond_buffer); > } > > printk( KERN_ALERT "Removing bond module\n"); > > } > > > int bond_open(struct inode *inode, struct file *filp) { > > > return 0; > } > > > int bond_release(struct inode *inode, struct file *filp) { > > > return 0; > } > > > 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); > > > /* if (*f_pos == 0) { > *f_pos+=1; > return 1; > } else { > return 0; > }*/ > } > > ssize_t bond_write( struct file *filp, char *buf, > size_t count, loff_t *f_pos) { > > // char *tmp; > > //tmp=buf+count-1; > copy_from_user(bond_buffer,buf,count<14 ? count : 14); > return 1; > } > > as per my understanding (may be wrong), issue is not with the copy_to/from_user. May be with the return values from bond_read/write function. Drivers read/write should return the number of bytes read or written. Here is the Makefile > > ifeq ($(KERNELRELEASE),) > KERNELDIR ?= /lib/modules/$(shell uname -r)/build > PWD := $(shell pwd) > .PHONY: build clean > build: > $(MAKE) -C $(KERNELDIR) M=$(PWD) modules > clean: > rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c > rm -rf modules.order Module.symvers > else > $(info Building with KERNELRELEASE =${KERNELRELEASE}) > obj-m := bond.o > > endif > > and here is the strace > 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) = ? > > so copy_from_user and copy_to_write are not doing what I expect them to do > this is not clear to me. >
