Kernel Hackers

In this blog We will share our experiences in different areas of Software Systems. This will help us manage our thoughts and may help you in some ways. Welcome!

Tuesday, January 27, 2009

Create Simple character Device Driver.

//Created By Majid Sadeghi Alavijeh (Majid.Sadeghi.Alavijeh@gmail.com)
/*
Steps For Creare Character Device Driver :

1.crete Strcuture That Contains propeties About Our Driver , it should contains an object of
Type cdev that point to our dvice.

struct memory_cdev
{
unsigned short current_pointer;
unsigned int size;
struct cdev c_dev;
char name[20];
};

2.create an object of type dev_t that contains minor and major number from our driver .
3.Create an Pointer Object Class for our device driver
4.Create File Operations For Our Driver . in this case i add some basic of this operations to my structure

static struct file_operations memory_fops =
{
.read=memory_read,
.write=memory_write,
.open=memory_open,
.release=memory_release
};

4.alloc_chrdev_region(refrence of type dev_t , 0 , NUMBER_OF_DRIVER , DEVICE_NAME ) :
this function fill our dev_t poineter with minor and major number if we pass 0 as second arguman.
we can get minor and major number rom dev_t :
MINOR(dev_t object):return minor number
MAJOR(dev_t object):return major number
6.myClass = class_create( THIS_MODULE , DEVICE_NAME );
this function create class in sys branches for our driver and udev make its node in /dev
7..cdev_init( &(p_memory_cdev->c_dev) , &memory_fops);
attach our device file operations to our device.
8.cdev_add(&(p_memory_cdev->c_dev) , device_structure , 1 ):
sepicify our device structure's cdev field's MINOR and MAJOR number.
in this function 1 specify number of devices (minors) that this driver controlls.
9.device_create(myClass , NULL , device_structure , NULL , "MemoryMajid" );
create class nodes for our dev_t structure and its node in /dev banch be created with name "MemoryMajid".
10..for delete our device from our devices list we use cdev_del(&p_memory_cdev->c_dev);
11.for make major nad minors free we use unregister_chrdev_region(device_structure , NUMBER_OF_DRIVER );
12.device_destroy(myClass , device_structure): used for delete attached devices.
13.class_destroy(myClass) : used for delete created class in our sys files.

attentions :
1.memory_read , memory_write , memory_open and memory_release are call back functions that be
appeared :
memory_read : when user space read device.
memory_write : when user space write somethings to this driver.
memory_open : when user space open it.
memory_release : when user space close it.
2.our call back function signatures :
memory_open : static int memory_open(struct inode *inode , struct file *flip);
memory_release : static int memory_release(struct inode *inode , struct file * flip);
memory_read : static ssize_t memory_read(struct file* flip , char * buf , size_t count , loff_t * f_ops);
memory_write : static ssize_t memory_write(struct file* flip , char * buf , size_t count , loff_t * f_ops);
3.some important used functions in these operations :
-copy_from_user(destination buffer ,source buffer , count) : this function be used in write call back function
and source buffer get as input from out function and buffer is our use memory in driver source code.
-copy_to_user( destination buffer , source buffer , count ) ; this function copy source context in to destination
, be used in read call back function , commonly , source buffer is allocated memory in our source code and
destination buffer is read call back function input parameter.
-since user space uses while(read(....)){...} , we should return 0 for end of read operation.i.e . if we return
1 all times , our program ingage in infinite loop.
4.kmalloc( count , GFP_KERNEL) : create count byte with GFP_KERNEL flag for our memory allocation.
*/




#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 */
#include "linux/cdev.h"
#include "linux/device.h"


MODULE_DESCRIPTION("Memory Majid");
MODULE_AUTHOR("majid (majid.sadeghi.alavijeh@gmail.com)");
MODULE_LICENSE("GPL");

static int memory_open(struct inode *inode , struct file *flip);
static int memory_release(struct inode *inode , struct file * flip);
static ssize_t memory_read(struct file* flip , char * buf , size_t count , loff_t * f_ops);
static ssize_t memory_write(struct file* flip , char * buf , size_t count , loff_t * f_ops);
static void memory_exit(void);
static int memory_init(void);


static int memory_major ;
static int memory_minor;
static char * memory_buffer;
static dev_t device_structure;
static struct class *myClass ;
#define DEVICE_NAME "majidtest"
#define VER2
#define NUMBER_OF_DRIVER 1 //determine minor ranges


struct memory_cdev
{
unsigned short current_pointer;
unsigned int size;
struct cdev c_dev;
char name[20];
}*p_memory_cdev;
//typedef static p_memory_cdev PMemory_cdev;


enum DeviceState
{
ds_open , ds_close
};

static enum DeviceState device_state;

static struct file_operations memory_fops = {
.read=memory_read,
.write=memory_write,
.open=memory_open,
.release=memory_release
};

static int memory_createDevice()
{
#ifdef VER1
if ( ( memory_major = register_chrdev( 0 , DEVICE_NAME , &memory_fops) ) < memory_major =" MAJOR(device_structure);" memory_minor =" MINOR(device_structure);" myclass =" class_create(" p_memory_cdev =" kmalloc(sizeof(struct">name , "MemoryMajid");
cdev_init( &(p_memory_cdev->c_dev) , &memory_fops);
p_memory_cdev->c_dev.owner = THIS_MODULE;
printk("IN Initilized\n");

if(cdev_add(&(p_memory_cdev->c_dev) , device_structure , 1 ))
{
printk("Bad CDEV\n");
return -1;
}

device_create(myClass , NULL , device_structure , NULL , "MemoryMajid" );

printk("Device Created Successfully\n");
return 0;
}
}





static int memory_memoryInit()
{
if((memory_buffer = kmalloc( 1 , GFP_KERNEL)) < device_state ="=" device_state =" ds_open;" device_state =" ds_close;" res =" copy_to_user(" f_ops ="=" tmp =" buf+count-2;//" tmp ="=" device_state =" ds_close;">=0 && memory_memoryInit()>=0 && memory_init_class()>=0)
{
printk( "Memory Majid : Major Number is %d :\n " , memory_major);
printk( "Memory Majid : Devices Init\n" );
return 0;
}
// else
// {
// printk(KERN_DEBUG "Memory Majid : Memory Should exit immediately.");
//memory_exit();
return 0;
// }
}

static void memory_exit(void)
{
#ifdef VER1
unregister_chrdev(memory_major , DEVICE_NAME);
#endif
#ifdef VER2
cdev_del(&p_memory_cdev->c_dev);
unregister_chrdev_region(device_structure , NUMBER_OF_DRIVER );
device_destroy(myClass , device_structure);
class_destroy(myClass);
kfree(p_memory_cdev);
#endif
// printk(KERN_ALERT "Memory Majid : Error in Closing Module.");
// else
{
memory_memoryFree();
printk( "Memory Majid : Devices Exited.\n" );
}
printk("*********************************************************************************\n");
}

module_init(memory_init);
module_exit(memory_exit);

This Is My First Post

Dear My Friends ,
Thanks For Your Attention :D

Tuesday, September 18, 2007

Wellcome

In this blog I will post some articles about my experiences in Software Systems. This will manage my thoughts and may even help you in some ways.