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;
}

Reply via email to