On Sat, Sep 25, 2010 at 7:34 PM, Bond <jamesbond.2k.g@xxxxxxxxx> wrote:
On Fri, Sep 24, 2010 at 5:41 PM, sri <bskmohan@xxxxxxxxx> wrote:what part is not able to understand?Here is a program I wrotebut 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.
Drivers read/write should return the number of bytes read or written.
Here is the Makefileifeq ($(KERNELRELEASE),)KERNELDIR ?= /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd).PHONY: build cleanbuild:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.crm -rf modules.order Module.symverselse$(info Building with KERNELRELEASE =${KERNELRELEASE})obj-m := bond.o
endifand here is the stracemmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2a2f03b000write(1, "abcde", 5) = 1write(1, "bcde", 4) = 1write(1, "cde", 3) = 1write(1, "de", 2) = 1write(1, "e", 1) = 1close(1) = 0munmap(0x7f2a2f03b000, 4096) = 0close(2) = 0exit_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.