Another version of a simple char driver (Using x86_64 VMware)

Once the module is Live, Use
HEAD -c {no.of.bytes} /dev/mycharDevice for read operation
echo “” > /dev/mycharDevice for write operation

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#define DEVICE_NAME "mycharDevice"
#define CLASS_NAME "mycharClass"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("PraveenMax");

//Function prototypes for file_op
static int device_open(struct inode *, struct file *);
static int device_close(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t , loff_t *);
static ssize_t device_write(struct file *, const char *, size_t , loff_t *);

static struct file_operations my_fops={
	.owner = THIS_MODULE,
	.read  = device_read,
	.write = device_write,
	.open  = device_open,
	.release = device_close,
};	

//module variables
static struct class* mycharClass = NULL;
static struct device* mycharDevice = NULL;
static int majorNumber;

static char myBuffer[100]={0};
static short readPos=0;
static int times = 0;

static int device_open(struct inode *inode, struct file *filep)
{
	times++;
	printk(KERN_ALERT "MYCHARDEVICE Device opened %d times \n",times);
	return 0;
}

static int device_close(struct inode *inode, struct file *fileop)
{
	printk(KERN_ALERT "MYCHARDEVICE Device closed\n");
	return 0;
}

//Read len length of data from kernel buffer and stores in userbuffer "buff"
static ssize_t device_read(struct file *fileop, char *buff, size_t len, loff_t *f_pos)
{
	printk(KERN_ALERT "Reading from the device of Data length : %d \n", len);
	
	int bytesRead = 0;
	
	while(len>0)
	{
		//copies the kernel buffer "myBuffer" into userbuffer buff
		put_user(myBuffer[readPos++], buff++);
		len--;
		bytesRead++;
	}
	
	return bytesRead;
}

//Writes the data from userbuffer "buff" of length "len" into kernel buffer "msg"s
static ssize_t device_write(struct file *fileop, const char *buff, size_t len, loff_t *off)
{
	printk(KERN_ALERT "Writing to the device. Data length : %d \n", len);
	
	int bytesWritten = 0; //also acts as buffer index
	memset(myBuffer,0,100); //reset the buffer values
	readPos=0;//reset kernelbuffer pointer
	
	while(len >0)
	{
		myBuffer[bytesWritten] = buff[bytesWritten];
		bytesWritten++;
		len--;
	}

	return bytesWritten;
}
 
static int __init load_module(void)
{
	printk(KERN_ALERT "Mychardriver :: Loading the module \n");

	//Dynamically get the Major Number
	majorNumber = register_chrdev(0, DEVICE_NAME, &my_fops);

	if(majorNumber < 0)
	{
		printk(KERN_ALERT "*** Unable to register MYCHARDRIVER driver : %d\n", majorNumber);
		return majorNumber;
	}
	
	printk(KERN_ALERT "Obtained a Major number !\n");

	//Create a device class for my char driver (appears in /sys/class )
	mycharClass = class_create(THIS_MODULE, CLASS_NAME);
	if(IS_ERR(mycharClass))
	{
		unregister_chrdev(majorNumber, DEVICE_NAME);
		printk(KERN_ALERT "Failed to register the char device \n");
		return PTR_ERR(mycharClass);
	}
	printk(KERN_ALERT "Device class created successfully!\n");

	
	//Create the device node and register it (appears in /dev/DEVICE_NAME )
	mycharDevice = device_create(mycharClass, NULL, MKDEV(majorNumber,0), NULL, DEVICE_NAME);
	if(IS_ERR(mycharDevice))
	{
		class_destroy(mycharClass);
		unregister_chrdev(majorNumber, DEVICE_NAME);
		printk(KERN_ALERT "Failed the create Device node ! \n");
		return PTR_ERR(mycharDevice);
	}
	printk(KERN_ALERT "Device node created successfully ! \n");

	//some initializations
	memset(myBuffer,0,100); //reset the buffer values


 	return 0;
}

static void __exit unload_module(void)
{
	device_destroy(mycharClass, MKDEV(majorNumber, 0) );//destroy the device
	class_unregister(mycharClass);						 //Unregister the device class
	class_destroy(mycharClass); 						 //destroy the class
	unregister_chrdev(majorNumber, DEVICE_NAME);    	 //Unregister the major number
	printk(KERN_ALERT "MYCHARDRIVER Module exited!!\n");
} 

module_init(load_module);
module_exit(unload_module);

About PraveenMax
My Interests: ------------------ Programming , Drawing & Music

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: