PDA

View Full Version : error in newbie's character drivers code



jamesbon
September 12th, 2010, 03:26 PM
From this linkhttp://www.freesoftwaremagazine.com/articles/drivers_linux?page=0,0


I wrote following program




It is to have a character device driver with Major number 60 and do read write


/* 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 */




/* Declaration of memory.c functions */
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)
{

/* Transfering data to user space */
copy_to_user(buf,bond_buffer,1);


/* Changing reading position as best suits */
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,tmp,1);
return 1;
} ;
void bond_exit(void);
int bond_init(void);


/* Structure that declares the usual file */
/* access functions */
struct file_operations bond_fops = {
read: bond_read,
write: bond_write,
open: bond_open,
release: bond_release
};


/* Global variables of the driver */
/* Major number */
int bond_major = 60;
/* Buffer to store data */
char *bond_buffer;


static int bond_init(void) {
printk("<1> Hello bond new driver!\n");
int result;


/* Registering device */
result = register_chrdev(bond_major, "bond", &bond_fops);
if (result < 0) {
printk(
"<1>memory: cannot obtain major number %d\n", bond_major);
return result;
}


/* Allocating memory for the buffer */
bond_buffer = kmalloc(1, GFP_KERNEL);
if (!bond_buffer) {
result = -ENOMEM;
goto fail;
}
memset(bond_buffer, 0, 1);


printk("<1>Inserting bond module\n");
return 0;


fail:
bond_exit();
return result;
return 0;
}


static void bond_exit(void) {
printk("<1> Bye, bond world\n");
/* Freeing the major number */
unregister_chrdev(bond_major, "bond");


/* Freeing buffer memory */
if (bond_buffer) {
kfree(bond_buffer);
}


printk("<1>Removing bond module\n");




}


module_init(bond_init);
module_exit(bond_exit);


MODULE_AUTHOR("Bond");
MODULE_LICENSE("GPL");


But when I compiled above
I got following errors



/home/bond/driver/bond.c:5:26: error: linux/config.h: No such file or directory
/home/bond/driver/bond.c: In function ‘bond_read’:
/home/bond/driver/bond.c:25: error: ‘bond_buffer’ undeclared (first use in this function)
/home/bond/driver/bond.c:25: error: (Each undeclared identifier is reported only once
/home/bond/driver/bond.c:25: error: for each function it appears in.)
/home/bond/driver/bond.c: In function ‘bond_write’:
/home/bond/driver/bond.c:43: error: ‘bond_buffer’ undeclared (first use in this function)
/home/bond/driver/bond.c: At top level:
/home/bond/driver/bond.c:53: warning: initialization from incompatible pointer type
/home/bond/driver/bond.c:64: error: static declaration of ‘bond_init’ follows non-static declaration
/home/bond/driver/bond.c:47: note: previous declaration of ‘bond_init’ was here
/home/bond/driver/bond.c: In function ‘bond_init’:
/home/bond/driver/bond.c:66: warning: ISO C90 forbids mixed declarations and code
/home/bond/driver/bond.c: At top level:
/home/bond/driver/bond.c:93: error: static declaration of ‘bond_exit’ follows non-static declaration
/home/bond/driver/bond.c:46: note: previous declaration of ‘bond_exit’ was here
make[2]: *** [/home/bond/driver/bond.o] Error 1
make[1]: *** [_module_/home/bond/driver] Error 2
make: *** [build] Error 2

What is the error in above code any idea?




Here is the corresponding 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

worseisworser
September 12th, 2010, 03:51 PM
I think you're missing the Linux kernel headers:



sudo aptitude search linux-headers


..so something like this, based on your installed kernel, perhaps:



sudo aptitude install linux-headers-`uname -r`

jamesbon
September 12th, 2010, 07:20 PM
Ok by now I have been able to fix this problem.

1) config.h has been dropped from 2.6.19 series of kernels so that was one error

2) the program was kept in a directory whose directory name had a blank space in between this was also giving me errors
3) I had tried the functions with my name rather than memory_open,memory_read,memory_release
I am not clear if this type of use is wrong.

I had tried the functions with my name rather than memory_open,memory_read,memory_release
I am not clear if this type of use is wrong.

The driver is working but it if I do

echo -n abcdefg > /dev/memory

then on doing cat /dev/memory
only last g is coming and all previous words which I gave abcdef are dropped out
any idea on what might be the error.