Linux Kernel Driver Program:12_sysfs_kernel_driver

Linux Kernel Driver Program:

12_sysfs_kernel_driver

neelkanth_surekha#cat Read\ me 

This directory contains three files.
1.Driver
2.Make File
3.User Application

Driver is running on kernel space
Makefile is used to build the kernel linux device driver


neelkanth_surekha#cat driver.c 

/* 
 * Sysfs is a virtual filesystem exported by the kernel, similar to /proc. 
 * The files in Sysfs contain information about devices and drivers. Some 
 * files in Sysfs are even writable, for configuration and control of devices 
 * attached to the system. Sysfs is always mounted on /sys.
 * 
 * The directories in Sysfs contain the hierarchy of devices, 
 * as they are attached to the computer. 
 *
 * "Sysfs" is the commonly used method to export system information 
 * from the kernel space to the user space for specific devices. 
 * The "sysfs" is tied to the device driver model of the kernel. 
 * The "procfs" is used to export the process specific information 
 * and the "debugfs" is used to used for exporting the debug information 
 * by the developer.
 ******************************************************************************************
 * There are many ways to Communicate between the User space and Kernel Space, they are:
 ******************************************************************************************
 * 1. IOCTL
 * 2. Procfs
 * 3. Sysfs                    <---------------------------------
 * 4. Configfs
 * 5. Debugfs
 * 6. Sysctl
 * 7. UDP Sockets
 * 8. Netlink Sockets*
 */

#if 0
#############################################################################
 Heart of the sysfs model is the Kobject. 
 Kobject is the glue that binds the sysfs and the kernel, 
 which is represented by struct kobject.
 A struct kobject represents a kernel object, maybe a device or so, 
 such as the things that show up as directory in the sysfs filesystem.
#############################################################################
#endif


/*********************************************************************** 
 *                         OUTPUT
 ***********************************************************************  
neelkanth_surekha#pwd
/sys/kernel
neelkanth_surekha#cd dummy_sysfs/
neelkanth_surekha#ls
dummy_value
neelkanth_surekha#sudo cat dummy_value 
[sudo] password for neelkanth_surekha: 
0

neelkanth_surekha#sudo chmod 777 dummy_value 
neelkanth_surekha#sudo echo 1 > dummy_value 
neelkanth_surekha#cat dummy_value 
1
************************************************************************/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include<linux/slab.h>                 //kmalloc()
#include<linux/uaccess.h>              //copy_to/from_user()
#include<linux/sysfs.h> 
#include<linux/kobject.h> 


volatile int dummy_value = 0;


dev_t dev = 0;
static struct class *dev_class;
static struct cdev dummy_cdev;
struct kobject *kobj_ref;

static int __init dummy_driver_init(void);
static void __exit dummy_driver_exit(void);

/*************** Driver Fuctions **********************/
static int dummy_open(struct inode *inode, struct file *file);
static int dummy_release(struct inode *inode, struct file *file);
static ssize_t dummy_read(struct file *filp, 
                char __user *buf, size_t len,loff_t * off);
static ssize_t dummy_write(struct file *filp, 
                const char *buf, size_t len, loff_t * off);

/*************** Sysfs Fuctions **********************/
static ssize_t sysfs_show(struct kobject *kobj, 
                struct kobj_attribute *attr, char *buf);
static ssize_t sysfs_store(struct kobject *kobj, 
                struct kobj_attribute *attr, char *buf, size_t count);

struct kobj_attribute dummy_attr = __ATTR(dummy_value, 0660, sysfs_show, sysfs_store);

static struct file_operations fops =
{
        .owner          = THIS_MODULE,
        .read           = dummy_read,
        .write          = dummy_write,
        .open           = dummy_open,
        .release        = dummy_release,
};

static ssize_t sysfs_show(struct kobject *kobj, 
                struct kobj_attribute *attr, char *buf)
{
        printk(KERN_INFO "Sysfs - Read!!!\n");
        return sprintf(buf, "%d", dummy_value);
}

static ssize_t sysfs_store(struct kobject *kobj, 
                struct kobj_attribute *attr, char *buf, size_t count)
{
        printk(KERN_INFO "Sysfs - Write!!!\n");
        sscanf(buf,"%d",&dummy_value);
        return count;
}

static int dummy_open(struct inode *inode, struct file *file)
{
        printk(KERN_INFO "Device File Opened...!!!\n");
        return 0;
}

static int dummy_release(struct inode *inode, struct file *file)
{
        printk(KERN_INFO "Device File Closed...!!!\n");
        return 0;
}

static ssize_t dummy_read(struct file *filp, 
                char __user *buf, size_t len, loff_t *off)
{
        printk(KERN_INFO "Read function\n");
        return 0;
}
static ssize_t dummy_write(struct file *filp, 
                const char __user *buf, size_t len, loff_t *off)
{
        printk(KERN_INFO "Write Function\n");
        return 0;
}


static int __init dummy_driver_init(void)
{
        /*Allocating Major number*/
        if((alloc_chrdev_region(&dev, 0, 1, "dummy_Dev")) <0){
                printk(KERN_INFO "Cannot allocate major number\n");
                return -1;
        }
        printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));

        /*Creating cdev structure*/
        cdev_init(&dummy_cdev, &fops);
        dummy_cdev.owner = THIS_MODULE;
        dummy_cdev.ops = &fops;

        /*Adding character device to the system*/
        if((cdev_add(&dummy_cdev, dev, 1)) < 0){
            printk(KERN_INFO "Cannot add the device to the system\n");
            goto r_class;
        }

        /*Creating struct class*/
        if((dev_class = class_create(THIS_MODULE, "dummy_class")) == NULL){
            printk(KERN_INFO "Cannot create the struct class\n");
            goto r_class;
        }

        /*Creating device*/
        if((device_create(dev_class,NULL, dev, NULL, "dummy_device")) == NULL){
            printk(KERN_INFO "Cannot create the Device 1\n");
            goto r_device;
        }

        /*Creating a directory in /sys/kernel/ */
        kobj_ref = kobject_create_and_add("dummy_sysfs", kernel_kobj);

        /*Creating sysfs file for dummy_value*/
        if(sysfs_create_file(kobj_ref, &dummy_attr.attr)){
                printk(KERN_INFO"Cannot create sysfs file......\n");
                goto r_sysfs;
    }
        printk(KERN_INFO "Device Driver Insert...Done!!!\n");
    return 0;

r_sysfs:
        kobject_put(kobj_ref); 
        sysfs_remove_file(kernel_kobj, &dummy_attr.attr);

r_device:
        class_destroy(dev_class);
r_class:
        unregister_chrdev_region(dev,1);
        cdev_del(&dummy_cdev);
        return -1;
}

void __exit dummy_driver_exit(void)
{
        kobject_put(kobj_ref); 
        sysfs_remove_file(kernel_kobj, &dummy_attr.attr);
        device_destroy(dev_class,dev);
        class_destroy(dev_class);
        cdev_del(&dummy_cdev);
        unregister_chrdev_region(dev, 1);
        printk(KERN_INFO "Device Driver Remove...Done!!!\n");
}

module_init(dummy_driver_init);
module_exit(dummy_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Neelkanth Reddy <www.neelkanth.13@gmail.com>");
MODULE_DESCRIPTION("A simple device driver - SysFs");
MODULE_VERSION("1:1.0");

neelkanth_surekha#cat Makefile 

obj-m += driver.o

KDIR = /lib/modules/$(shell uname -r)/build


#e.g. : make -C /lib/modules/4.4.0-93-generic/build  M=/home/neelkanth_surekha/Device_Driver/8_IOCTL_Driver_code modules
all:
make -C $(KDIR)  M=$(shell pwd) modules

clean:
make -C $(KDIR)  M=$(shell pwd) clean

Linux Kernel Driver Program: 11_waitqueue_dynamic_Device_driver

neelkanth_surekha#cat Read\ me 

This directory contains three files.
1.Driver
2.Make File
3.User Application

Driver is running on kernel space
Makefile is used to build the kernel linux device driver


neelkanth_surekha#cat driver.c 

/* When you write a Linux  Driver or Module or Kernel Program, 
 * Some process should be wait or sleep for some event. There are 
 * several ways of handling sleeping and waking up in Linux, each 
 * suited to different needs. 
 *
 * 'Waitqueue' also one of the method to handle that case.
 *
 * Whenever a process must wait for an event (such as the arrival of 
 * data or the termination of a process), it should go to sleep. Sleeping 
 * causes the process to suspend execution, freeing the processor for other 
 * uses. After some time, the process will be woken up and will continue with
 *  its job when the event which we are waiting will be occurred.
 *
 * Wait queue is a mechanism provided in kernel to implement the wait. 
 * As the name itself suggests, "wait queue" is the list of processes 
 * waiting for an event. In other words, A wait queue is used to wait for someone
 * to wake you up when a certain condition is true. They must be used carefully
 * to ensure there is no race condition.
 **************************************************************************************
 * There are 3 important steps in Waitqueue.
 **************************************************************************************
 * 1. Initializing Waitqueue
 * 2. Queuing (Put the Task to sleep until the event comes)
 * 3. Waking Up Queued Task 
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/slab.h>                 //kmalloc()
#include <linux/uaccess.h>              //copy_to/from_user()

#include <linux/kthread.h>
#include <linux/wait.h>                // Required for the wait queues


uint32_t read_count = 0;
static struct task_struct *wait_thread;

dev_t dev = 0;
static struct class *dev_class;
static struct cdev dummy_cdev;
wait_queue_head_t wait_queue_dummy;
int wait_queue_flag = 0;

static int __init dummy_driver_init(void);
static void __exit dummy_driver_exit(void);

/*************** Driver Fuctions **********************/
static int dummy_open(struct inode *inode, struct file *file);
static int dummy_release(struct inode *inode, struct file *file);
static ssize_t dummy_read(struct file *filp, char __user *buf, size_t len,loff_t * off);
static ssize_t dummy_write(struct file *filp, const char *buf, size_t len, loff_t * off);


static struct file_operations fops =
{
        .owner          = THIS_MODULE,
        .read           = dummy_read,
        .write          = dummy_write,
        .open           = dummy_open,
        .release        = dummy_release,
};


static int wait_function(void *unused)
{
        
        while(1) {
                printk(KERN_INFO "Waiting For Event...\n");
                wait_event_interruptible(wait_queue_dummy, wait_queue_flag != 0 );
                if(wait_queue_flag == 2) {
                        printk(KERN_INFO "Event Came From Exit Function\n");
                        return 0;
                }
                printk(KERN_INFO "Event Came From Read Function - %d\n", ++read_count);
                wait_queue_flag = 0;
        }
        return 0;
}



static int dummy_open(struct inode *inode, struct file *file)
{
        printk(KERN_INFO "Device File Opened...!!!\n");
        return 0;
}

static int dummy_release(struct inode *inode, struct file *file)
{
        printk(KERN_INFO "Device File Closed...!!!\n");
        return 0;
}

static ssize_t dummy_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
        printk(KERN_INFO "Read Function\n");
        wait_queue_flag = 1;
        wake_up_interruptible(&wait_queue_dummy);
        return 0;
}
static ssize_t dummy_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
        printk(KERN_INFO "Write function\n");
        return 0;
}




static int __init dummy_driver_init(void)
{
        /*Allocating Major number*/
        if((alloc_chrdev_region(&dev, 0, 1, "dummy_Dev")) <0){
                printk(KERN_INFO "Cannot allocate major number\n");
                return -1;
        }
        printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));

        /*Creating cdev structure*/
        cdev_init(&dummy_cdev, &fops);
        dummy_cdev.owner = THIS_MODULE;
        dummy_cdev.ops = &fops;

        /*Adding character device to the system*/
        if((cdev_add(&dummy_cdev, dev, 1)) < 0){
            printk(KERN_INFO "Cannot add the device to the system\n");
            goto r_class;
        }

        /*Creating struct class*/
        if((dev_class = class_create(THIS_MODULE, "dummy_class")) == NULL){
            printk(KERN_INFO "Cannot create the struct class\n");
            goto r_class;
        }

        /*Creating device*/
        if((device_create(dev_class, NULL, dev, NULL, "dummy_device")) == NULL){
            printk(KERN_INFO "Cannot create the Device 1\n");
            goto r_device;
        }
        
        /* Initialize wait queue */
        init_waitqueue_head(&wait_queue_dummy);

        /* Create the kernel thread with name 'neel_WtThread' */
        wait_thread = kthread_create(wait_function, NULL, "neel_WtThread");
        if (wait_thread) {
                printk("Thread Created successfully\n");
                wake_up_process(wait_thread);
        } else
                printk(KERN_INFO "Thread creation failed\n");

        printk(KERN_INFO "Device Driver Insert...Done!!!\n");
    return 0;

r_device:
        class_destroy(dev_class);
r_class:
        unregister_chrdev_region(dev,1);
        return -1;
}

void __exit dummy_driver_exit(void)
{
        wait_queue_flag = 2;
        wake_up_interruptible(&wait_queue_dummy);
        device_destroy(dev_class,dev);
        class_destroy(dev_class);
        cdev_del(&dummy_cdev);
        unregister_chrdev_region(dev, 1);
    printk(KERN_INFO "Device Driver Remove...Done!!!\n");
}

module_init(dummy_driver_init);
module_exit(dummy_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Neelkanth Reddy <www.neelkanth.13@gmail.com>");
MODULE_DESCRIPTION("A simple device driver");
MODULE_VERSION("0:1.0");

neelkanth_surekha#cat Makefile 

obj-m += driver.o

KDIR = /lib/modules/$(shell uname -r)/build


#e.g. : make -C /lib/modules/4.4.0-93-generic/build  M=/home/neelkanth_surekha/Device_Driver/8_IOCTL_Driver_code modules
all:
make -C $(KDIR)  M=$(shell pwd) modules

clean:
make -C $(KDIR)  M=$(shell pwd) clean

Linux Kernel Driver Program: 10_waitqueue_static_Device_driver

Linux Kernel Driver Program: 10_waitqueue_static_Device_driver

neelkanth_surekha#cat Read\ me 

This directory contains three files.
1.Driver
2.Make File
3.User Application

Driver is running on kernel space
Makefile is used to build the kernel linux device driver

neelkanth_surekha#cat driver.c 

/* When you write a Linux  Driver or Module or Kernel Program, 
 * Some process should be wait or sleep for some event. There are 
 * several ways of handling sleeping and waking up in Linux, each 
 * suited to different needs. 
 *
 * 'Waitqueue' also one of the method to handle that case.
 *
 * Whenever a process must wait for an event (such as the arrival of 
 * data or the termination of a process), it should go to sleep. Sleeping 
 * causes the process to suspend execution, freeing the processor for other 
 * uses. After some time, the process will be woken up and will continue with
 *  its job when the event which we are waiting will be occurred.
 *
 * Wait queue is a mechanism provided in kernel to implement the wait. 
 * As the name itself suggests, "wait queue" is the list of processes 
 * waiting for an event. In other words, A wait queue is used to wait for someone
 * to wake you up when a certain condition is true. They must be used carefully
 * to ensure there is no race condition.
 **************************************************************************************
 * There are 3 important steps in Waitqueue.
 **************************************************************************************
 * 1. Initializing Waitqueue
 * 2. Queuing (Put the Task to sleep until the event comes)
 * 3. Waking Up Queued Task 
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/slab.h>                 //kmalloc()
#include <linux/uaccess.h>              //copy_to/from_user()

#include <linux/kthread.h>
#include <linux/wait.h>                // Required for the wait queues


uint32_t read_count = 0;
static struct task_struct *wait_thread;

DECLARE_WAIT_QUEUE_HEAD(wait_queue_dummy);

dev_t dev = 0;
static struct class *dev_class;
static struct cdev dummy_cdev;
int wait_queue_flag = 0;

static int __init dummy_driver_init(void);
static void __exit dummy_driver_exit(void);

/*************** Driver Fuctions **********************/
static int dummy_open(struct inode *inode, struct file *file);
static int dummy_release(struct inode *inode, struct file *file);
static ssize_t dummy_read(struct file *filp, char __user *buf, size_t len,loff_t * off);
static ssize_t dummy_write(struct file *filp, const char *buf, size_t len, loff_t * off);


static struct file_operations fops =
{
        .owner          = THIS_MODULE,
        .read           = dummy_read,
        .write          = dummy_write,
        .open           = dummy_open,
        .release        = dummy_release,
};


static int wait_function(void *unused)
{
        
        while(1) {
                printk(KERN_INFO "Waiting For Event...\n");
                wait_event_interruptible(wait_queue_dummy, wait_queue_flag != 0 );
                if(wait_queue_flag == 2) {
                        printk(KERN_INFO "Event Came From Exit Function\n");
                        return 0;
                }
                printk(KERN_INFO "Event Came From Read Function - %d\n", ++read_count);
                wait_queue_flag = 0;
        }
        return 0;
}



static int dummy_open(struct inode *inode, struct file *file)
{
        printk(KERN_INFO "Device File Opened...!!!\n");
        return 0;
}

static int dummy_release(struct inode *inode, struct file *file)
{
        printk(KERN_INFO "Device File Closed...!!!\n");
        return 0;
}

static ssize_t dummy_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
        printk(KERN_INFO "Read Function\n");
        wait_queue_flag = 1;
        wake_up_interruptible(&wait_queue_dummy);
        return 0;
}
static ssize_t dummy_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
        printk(KERN_INFO "Write function\n");
        return 0;
}




static int __init dummy_driver_init(void)
{
        /*Allocating Major number*/
        if((alloc_chrdev_region(&dev, 0, 1, "dummy_Dev")) <0){
                printk(KERN_INFO "Cannot allocate major number\n");
                return -1;
        }
        printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));

        /*Creating cdev structure*/
        cdev_init(&dummy_cdev,&fops);
        dummy_cdev.owner = THIS_MODULE;
        dummy_cdev.ops = &fops;

        /*Adding character device to the system*/
        if((cdev_add(&dummy_cdev,dev,1)) < 0){
            printk(KERN_INFO "Cannot add the device to the system\n");
            goto r_class;
        }

        /*Creating struct class*/
        if((dev_class = class_create(THIS_MODULE,"dummy_class")) == NULL){
            printk(KERN_INFO "Cannot create the struct class\n");
            goto r_class;
        }

        /*Creating device*/
        if((device_create(dev_class,NULL,dev,NULL,"dummy_device")) == NULL){
            printk(KERN_INFO "Cannot create the Device 1\n");
            goto r_device;
        }
        
        //Initialize wait queue
        init_waitqueue_head(&wait_queue_dummy);

        //Create the kernel thread with name 'mythread'
        wait_thread = kthread_create(wait_function, NULL, "Neel_Wt_Thr");
        if (wait_thread) {
                printk("Thread Created successfully\n");
                wake_up_process(wait_thread);
        } else
                printk(KERN_INFO "Thread creation failed\n");

        printk(KERN_INFO "Device Driver Insert...Done!!!\n");
    return 0;

r_device:
        class_destroy(dev_class);
r_class:
        unregister_chrdev_region(dev,1);
        return -1;
}

void __exit dummy_driver_exit(void)
{
        wait_queue_flag = 2;
        wake_up_interruptible(&wait_queue_dummy);
        device_destroy(dev_class,dev);
        class_destroy(dev_class);
        cdev_del(&dummy_cdev);
        unregister_chrdev_region(dev, 1);
    printk(KERN_INFO "Device Driver Remove...Done!!!\n");
}

module_init(dummy_driver_init);
module_exit(dummy_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Neelkanth Reddy <www.neelkanth.13@gmail.com>");
MODULE_DESCRIPTION("A simple device driver");
MODULE_VERSION("1.7");

neelkanth_surekha#cat Makefile 

obj-m += driver.o

KDIR = /lib/modules/$(shell uname -r)/build


#e.g. : make -C /lib/modules/4.4.0-93-generic/build  M=/home/neelkanth_surekha/Device_Driver/8_IOCTL_Driver_code modules
all:
make -C $(KDIR)  M=$(shell pwd) modules

clean:
make -C $(KDIR)  M=$(shell pwd) clean


Linux Kernel Driver Program: 9_Procfs_Device_driver

Linux Kernel Driver Program: 9_Procfs_Device_driver

neelkanth_surekha#cat Read\ me 

This directory contains three files.
1.Driver
2.Make File
3.User Application

Driver is running on kernel space
Makefile is used to build the kernel linux device driver
User application will running on the user space and communicate to driver on kernel space.

neelkanth_surekha#cat driver.c 

/* 
 * Operating system segregates virtual memory into kernel space and user space.  Kernel space 
 * is strictly reserved for running the kernel, kernel extensions, and most device drivers. 
 * In contrast, user space is the memory area where all user mode applications work and this 
 * memory can be swapped out when necessary. 
 */

#if 0
############################################################################################
There are many ways to Communicate between the User space and Kernel Space, they are:
############################################################################################
1. IOCTL
2. Procfs <---------------------
3. Sysfs
4. Configfs
5. Debugfs
6. Sysctl
7. UDP Sockets
8. Netlink Sockets

##################################################################################
##################################################################################
The proc entry can also be used to pass data to the kernel by writing into the 
kernel, so there can be two kinds of proc entries.

An entry that only reads data from the kernel space.
An entry that reads as well as writes data into and from kernel space.
##################################################################################
##################################################################################
#endif

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include<linux/slab.h>                 //kmalloc()
#include<linux/uaccess.h>              //copy_to/from_user()
#include <linux/ioctl.h>
#include<linux/proc_fs.h>

#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)

int32_t value = 0;
char dummy_array[20] = "dummy proc file\n";
static int len = 1;


dev_t dev = 0;
static struct class *dev_class;
static struct cdev dummy_cdev;

static int __init dummy_driver_init(void);
static void __exit dummy_driver_exit(void);
/*************** Driver Fuctions **********************/
static int dummy_open(struct inode *inode, struct file *file);
static int dummy_release(struct inode *inode, struct file *file);
static ssize_t dummy_read(struct file *filp, char __user *buf, size_t len,loff_t * off);
static ssize_t dummy_write(struct file *filp, const char *buf, size_t len, loff_t * off);
static long dummy_ioctl(struct file *file, unsigned int cmd, unsigned long arg);

/***************** Procfs Functions *******************/
static int open_proc(struct inode *inode, struct file *file);
static int release_proc(struct inode *inode, struct file *file);
static ssize_t read_proc(struct file *filp, char __user *buffer, size_t length,loff_t * offset);
static ssize_t write_proc(struct file *filp, const char *buff, size_t len, loff_t * off);

static struct file_operations fops =
{
    .owner          = THIS_MODULE,
    .read           = dummy_read,
    .write          = dummy_write,
    .open           = dummy_open,
    .unlocked_ioctl = dummy_ioctl,
    .release        = dummy_release,
};

static struct file_operations proc_fops = {
    .open = open_proc,
    .read = read_proc,
    .write = write_proc,
    .release = release_proc
};

static int open_proc(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "proc file opend.....\t");
    return 0;
}

static int release_proc(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "proc file released.....\n");
    return 0;
}

static ssize_t read_proc(struct file *filp, char __user *buffer, size_t length,loff_t * offset)
{
    printk(KERN_INFO "proc file read.....\n");
    if(len)
        len=0;
    else{
        len=1;
        return 0;
    }
    copy_to_user(buffer,dummy_array,20);

    return length;;
}

static ssize_t write_proc(struct file *filp, const char *buff, size_t len, loff_t * off)
{
    printk(KERN_INFO "proc file wrote.....\n");
    copy_from_user(dummy_array,buff,len);
    return len;
}

static int dummy_open(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "Device File Opened...!!!\n");
    return 0;
}

static int dummy_release(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "Device File Closed...!!!\n");
    return 0;
}

static ssize_t dummy_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
    printk(KERN_INFO "Readfunction\n");
    return 0;
}
static ssize_t dummy_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
    printk(KERN_INFO "Write Function\n");
    return 0;
}

static long dummy_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    switch(cmd) {
        case WR_VALUE:
            copy_from_user(&value ,(int32_t*) arg, sizeof(value));
            printk(KERN_INFO "Value = %d\n", value);
            break;
        case RD_VALUE:
            copy_to_user((int32_t*) arg, &value, sizeof(value));
            break;
    }
    return 0;
}


static int __init dummy_driver_init(void)
{
    /*Allocating Major number*/
    if((alloc_chrdev_region(&dev, 0, 1, "dummy_Dev")) <0){
        printk(KERN_INFO "Cannot allocate major number\n");
        return -1;
    }
    printk(KERN_INFO "Major = %d Minor = %d \n", MAJOR(dev), MINOR(dev));

    /*Creating cdev structure*/
    cdev_init(&dummy_cdev, &fops);
    dummy_cdev.owner = THIS_MODULE;
    dummy_cdev.ops = &fops;

    /*Adding character device to the system*/
    if((cdev_add(&dummy_cdev, dev, 1)) < 0){
        printk(KERN_INFO "Cannot add the device to the system\n");
        goto r_class;
    }

    /*Creating struct class*/
    if((dev_class = class_create(THIS_MODULE, "dummy_class")) == NULL){
        printk(KERN_INFO "Cannot create the struct class\n");
        goto r_class;
    }

    /*Creating device*/
    if((device_create(dev_class, NULL, dev, NULL, "dummy_device")) == NULL){
        printk(KERN_INFO "Cannot create the Device 1\n");
        goto r_device;
    }

    /*Creating Proc entry*/
    /* dummy_proc is the file created in proc file system */
    proc_create("dummy_proc", 0666, NULL, &proc_fops);

    printk(KERN_INFO "Device Driver Insert...Done!!!\n");
    return 0;

r_device:
    class_destroy(dev_class);
r_class:
    unregister_chrdev_region(dev,1);
    return -1;
}

void __exit dummy_driver_exit(void)
{
    remove_proc_entry("dummy_proc",NULL);
    device_destroy(dev_class,dev);
    class_destroy(dev_class);
    cdev_del(&dummy_cdev);
    unregister_chrdev_region(dev, 1);
    printk(KERN_INFO "Device Driver Remove...Done!!!\n");
}

module_init(dummy_driver_init);
module_exit(dummy_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Neelkanth Reddy <www.neelkanth.13@gmail.com>");
MODULE_DESCRIPTION("A simple device driver");
MODULE_VERSION("0:1.0");

neelkanth_surekha#cat Makefile 

obj-m += driver.o

KDIR = /lib/modules/$(shell uname -r)/build


#e.g. : make -C /lib/modules/4.4.0-93-generic/build  M=/home/neelkanth_surekha/Device_Driver/8_IOCTL_Driver_code modules
all:
make -C $(KDIR)  M=$(shell pwd) modules

clean:
make -C $(KDIR)  M=$(shell pwd) clean



Linux Kernel Driver Program: 8_IOCTL_Driver_code

Linux Kernel Driver Program: 8_IOCTL_Driver_code

neelkanth_surekha#cat Read\ me 

This directory contains three files.
1.Driver
2.Make File
3.User Application

Driver is running on kernel space
Makefile is used to build the kernel linux device driver
User application will running on the user space and communicate to driver on kernel space.


neelkanth_surekha#cat driver.c 

/* 
 * IOCTL is referred as Input and Output Control, which is used to talking to device drivers. 
 * This system call, available in most driver categories.  The major use of this is in case 
 * of handling some specific operations of a device for which the kernel does not have a system
 * call by default.
 *
 * Some real time applications of ioctl is Ejecting the media from a “cd” drive, to change the 
 * Baud Rate of Serial port, Adjust the Volume, Reading or Writing device registers, etc. We 
 * already have write and read function in our device driver. But it is not enough for all cases. 
 */

#if 0
############################################################################################
There are many ways to Communicate between the User space and Kernel Space, they are:
############################################################################################
1. IOCTL
2. Procfs
3. Sysfs
4. Configfs
5. Debugfs
6. Sysctl
7. UDP Sockets
8. Netlink Sockets
#endif

/***************************************************************************** 
 *                      Steps involved in IOCTL
 **************************************************************************** 
 * 1. Create IOCTL command in driver
 * 2. Write IOCTL function in driver
 * 3. Create IOCTL command in User space application
 * 4. Use IOCTL system call in User space
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include<linux/slab.h>                 //kmalloc()
#include<linux/uaccess.h>              //copy_to/from_user()
#include <linux/ioctl.h>


#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)

int32_t value = 0;

dev_t dev = 0;
static struct class *dev_class;
static struct cdev dummy_cdev;

static int __init dummy_driver_init(void);
static void __exit dummy_driver_exit(void);
static int dummy_open(struct inode *inode, struct file *file);
static int dummy_release(struct inode *inode, struct file *file);
static ssize_t dummy_read(struct file *filp, char __user *buf, size_t len,loff_t * off);
static ssize_t dummy_write(struct file *filp, const char *buf, size_t len, loff_t * off);
static long dummy_ioctl(struct file *file, unsigned int cmd, unsigned long arg);

static struct file_operations fops =
{
    .owner          = THIS_MODULE,
    .read           = dummy_read,
    .write          = dummy_write,
    .open           = dummy_open,
    .unlocked_ioctl = dummy_ioctl,
    .release        = dummy_release,
};

static int dummy_open(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "Device File Opened...!!!\n");
    return 0;
}

static int dummy_release(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "Device File Closed...!!!\n");
    return 0;
}

static ssize_t dummy_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
    printk(KERN_INFO "Read Function\n");
    return 0;
}
static ssize_t dummy_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
    printk(KERN_INFO "Write function\n");
    return 0;
}

static long dummy_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    switch(cmd) {
        case WR_VALUE:
            copy_from_user(&value ,(int32_t*) arg, sizeof(value));
            printk(KERN_INFO "Value = %d\n", value);
            break;
        case RD_VALUE:
            copy_to_user((int32_t*) arg, &value, sizeof(value));
            break;
    }
    return 0;
}


static int __init dummy_driver_init(void)
{
    /*Allocating Major number*/
    if((alloc_chrdev_region(&dev, 0, 1, "dummy_Dev")) <0){
        printk(KERN_INFO "Cannot allocate major number\n");
        return -1;
    }
    printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));

    /*Creating cdev structure*/
    cdev_init(&dummy_cdev,&fops);
    dummy_cdev.owner = THIS_MODULE;
    dummy_cdev.ops = &fops;

    /*Adding character device to the system*/
    if((cdev_add(&dummy_cdev, dev, 1)) < 0){
        printk(KERN_INFO "Cannot add the device to the system\n");
        goto r_class;
    }

    /*Creating struct class*/
    if((dev_class = class_create(THIS_MODULE, "dummy_class")) == NULL){
        printk(KERN_INFO "Cannot create the struct class\n");
        goto r_class;
    }

    /*Creating device*/
    if((device_create(dev_class, NULL, dev, NULL, "dummy_device")) == NULL){
        printk(KERN_INFO "Cannot create the Device 1\n");
        goto r_device;
    }
    printk(KERN_INFO "Device Driver Insert...Done!!!\n");
    return 0;

r_device:
    class_destroy(dev_class);
r_class:
    unregister_chrdev_region(dev,1);
    return -1;
}

void __exit dummy_driver_exit(void)
{
    device_destroy(dev_class,dev);
    class_destroy(dev_class);
    cdev_del(&dummy_cdev);
    unregister_chrdev_region(dev, 1);
    printk(KERN_INFO "Device Driver Remove...Done!!!\n");
}

module_init(dummy_driver_init);
module_exit(dummy_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Neelkanth Reddy <www.neelkanth.13@gmail.com>");
MODULE_DESCRIPTION("A simple device driver");
MODULE_VERSION("1.5");



neelkanth_surekha#cat test_app.c 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<sys/ioctl.h>

#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)

int main()
{
    int fd;
    int32_t value, number;
    printf("*********************************\n");

    printf("\nOpening Driver\n");
    fd = open("/dev/dummy_device", O_RDWR);
    if(fd < 0) {
        printf("Cannot open device file '/dev/dummy_device'\n");
        return 0;
    }

    printf("Enter the Value to send\n");
    scanf("%d",&number);

    printf("Writing Value to Driver\n");
    ioctl(fd, WR_VALUE, (int32_t*) &number); 

    printf("Reading Value from Driver\n");
    ioctl(fd, RD_VALUE, (int32_t*) &value);

    printf("Value is %d\n", value);

    printf("Closing Driver\n");
    close(fd);
}


neelkanth_surekha#cat Makefile 

obj-m += driver.o

KDIR = /lib/modules/$(shell uname -r)/build


#e.g. : make -C /lib/modules/4.4.0-93-generic/build  M=/home/neelkanth_surekha/Device_Driver/8_IOCTL_Driver_code modules
all:
make -C $(KDIR)  M=$(shell pwd) modules

clean:
make -C $(KDIR)  M=$(shell pwd) clean

Linux Kernel Driver Program: 7_Real_Device_Driver

Linux Kernel Driver Program: 7_Real_Device_Driver

neelkanth_surekha#cat Read\ me 

This directory contains three files.
1.Driver
2.Make File
3.User Application

Driver is running on kernel space
Makefile is used to build the kernel linux device driver
User application will running on the user space and communicate to driver on kernel space.

neelkanth_surekha#cat driver.c 

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include<linux/slab.h>                 //kmalloc()
#include<linux/uaccess.h>              //copy_to/from_user()


#define mem_size        1024

dev_t dev = 0;
static struct class *dev_class;
static struct cdev dummy_device_cdev;
uint8_t *kernel_buffer;

static int __init dummy_device_driver_init(void);
static void __exit dummy_device_driver_exit(void);
static int dummy_device_open(struct inode *inode, struct file *file);
static int dummy_device_release(struct inode *inode, struct file *file);
static ssize_t dummy_device_read(struct file *filp, char __user *buf, size_t len,loff_t * off);
static ssize_t dummy_device_write(struct file *filp, const char *buf, size_t len, loff_t * off);

static struct file_operations fops =
{
        .owner          = THIS_MODULE,
        .read           = dummy_device_read,
        .write          = dummy_device_write,
        .open           = dummy_device_open,
        .release        = dummy_device_release,
};

static int dummy_device_open(struct inode *inode, struct file *file)
{
        /*Creating Physical memory*/
        if((kernel_buffer = kmalloc(mem_size , GFP_KERNEL)) == 0){
            printk(KERN_INFO "Cannot allocate memory in kernel\n");
            return -1;
        }
        printk(KERN_INFO "Device File Opened...!!!\n");
        return 0;
}

static int dummy_device_release(struct inode *inode, struct file *file)
{
        kfree(kernel_buffer);
        printk(KERN_INFO "Device File Closed...!!!\n");
        return 0;
}

static ssize_t dummy_device_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
        copy_to_user(buf, kernel_buffer, mem_size);
        printk(KERN_INFO "Data Write : Done!\n");
        return mem_size;
}
static ssize_t dummy_device_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
        copy_from_user(kernel_buffer, buf, len);
        printk(KERN_INFO "Data Read : Done!\n");
        return len;
}


static int __init dummy_device_driver_init(void)
{
        /*Allocating Major number*/
        if((alloc_chrdev_region(&dev, 0, 1, "dummy_device_Dev")) <0){
                printk(KERN_INFO "Cannot allocate major number\n");
                return -1;
        }
        printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));

        /*Creating cdev structure*/
        cdev_init(&dummy_device_cdev,&fops);
        dummy_device_cdev.owner = THIS_MODULE;
        dummy_device_cdev.ops = &fops;

        /*Adding character device to the system*/
        if((cdev_add(&dummy_device_cdev,dev,1)) < 0){
            printk(KERN_INFO "Cannot add the device to the system\n");
            goto r_class;
        }

        /*Creating struct class*/
        if((dev_class = class_create(THIS_MODULE,"dummy_device_class")) == NULL){
            printk(KERN_INFO "Cannot create the struct class\n");
            goto r_class;
        }

        /*Creating device*/
        if((device_create(dev_class,NULL,dev,NULL,"dummy_driver_device")) == NULL){
            printk(KERN_INFO "Cannot create the Device 1\n");
            goto r_device;
        }
        printk(KERN_INFO "Device Driver Insert...Done!!!\n");
return 0;

r_device:
        class_destroy(dev_class);
r_class:
        unregister_chrdev_region(dev,1);
        return -1;
}

void __exit dummy_device_driver_exit(void)
{
        device_destroy(dev_class,dev);
        class_destroy(dev_class);
        cdev_del(&dummy_device_cdev);
        unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Device Driver Remove...Done!!!\n");
}

module_init(dummy_device_driver_init);
module_exit(dummy_device_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Neelkanth <www.neelkanth.13@gmail.com>");
MODULE_DESCRIPTION("A simple device driver");
MODULE_VERSION("0:1.0");


neelkanth_surekha#cat test_app.c  [User space application code]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int8_t write_buf[1024];
int8_t read_buf[1024];
int main()
{
        int fd;
        char option;
        printf("*********************************\n");

        chmod("/dev/dummy_driver_device", 0777);

        fd = open("/dev/dummy_driver_device", O_RDWR);
        if(fd < 0) {
                printf("Cannot open device file...\n");
                return 0;
        }

        while(1) {
                printf("****Please Enter the Option******\n");
                printf("        1. Write               \n");
                printf("        2. Read                 \n");
                printf("        3. Exit                 \n");
                printf("*********************************\n");
                scanf(" %c", &option);
                printf("Your Option = %c\n", option);
                
                switch(option) {
                        case '1':
                                printf("Enter the string to write into driver :");
                                scanf("  %[^\t\n]s", write_buf);
                                printf("Data Writing ...");
                                write(fd, write_buf, strlen(write_buf)+1);
                                printf("Done!\n");
                                break;
                        case '2':
                                printf("Data Reading ...");
                                read(fd, read_buf, 1024);
                                printf("Done!\n\n");
                                printf("Data = %s\n\n", read_buf);
                                break;
                        case '3':
                                close(fd);
                                exit(1);
                                break;
                        default:
                                printf("Enter Valid option = %c\n",option);
                                break;
                }
        }
        close(fd);
}


neelkanth_surekha#cat Makefile 

obj-m += driver.o

KDIR = /lib/modules/$(shell uname -r)/build


all:
make -C $(KDIR)  M=$(shell pwd) modules

clean:
make -C $(KDIR)  M=$(shell pwd) clean



Linux Kernel Driver Program: 6_File_opertions_device_driver

Linux Kernel Driver Program: 6_File_opertions_device_driver

neelkanth_surekha#cat hello_world_module.c 

/************************************************************************
 *
 * neelkanth_surekha#   sudo insmod hello_world_module.ko
 * neelkanth_surekha#   ls -lt /dev | grep dummy
 * crw-------  1 root root    242,   0 Jan 26 13:54 dummy_device_device
 *
 * neelkanth_surekha#   sudo rmmod hello_world_module.ko
 * neelkanth_surekha#   ls -lt /dev | grep dummy
 *
 ***************************************************************************/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>

/* the dev_t for the char device to be added */
dev_t dev = 0;
/* pointer to the struct "class" that this device should be registered to */
static struct class *dev_class;
/* Character device structure */
static struct cdev dummy_device_cdev;

static int __init dummy_device_driver_init(void);
static void __exit dummy_device_driver_exit(void);
static int dummy_device_open(struct inode *inode, struct file *file);
static int dummy_device_release(struct inode *inode, struct file *file);
static ssize_t dummy_device_read(struct file *filp, char __user *buf, size_t len,loff_t * off);
static ssize_t dummy_device_write(struct file *filp, const char *buf, size_t len, loff_t * off);

static struct file_operations fops =
{
    .owner          = THIS_MODULE,
    .read           = dummy_device_read,
    .write          = dummy_device_write,
    .open           = dummy_device_open,
    .release        = dummy_device_release,
};

static int dummy_device_open(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "Driver Open Function Called...!!!\n");
    return 0;
}

static int dummy_device_release(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "Driver Release Function Called...!!!\n");
    return 0;
}

static ssize_t dummy_device_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
    printk(KERN_INFO "Driver Read Function Called...!!!\n");
    return 0;
}
static ssize_t dummy_device_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
    printk(KERN_INFO "Driver Write Function Called...!!!\n");
    return len;
}

/*******************************************************************************************
 * How Applications will communicate with Hardware device
 * 
 * Step 1: Application
 * Step 2: Device File or device Node
 * Step 3: Major and Minor Number
 * Step 4: Device Driver
 * Step 5: Hardware 
 ******************************************************************************************/

static int __init dummy_device_driver_init(void)
{
    /* Allocating Major number */
    if((alloc_chrdev_region(&dev, 0, 1, "dummy_device_Dev")) <0){
        printk(KERN_INFO "Cannot allocate major number\n");
        return -1;
    }
    printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));

    /*Creating cdev structure*/
    /* In linux kernel struct "inode" structure is used to represent files. Therefore, it is 
     * different from the file structure that represents an "open file descriptor". 
     * There can be numerous file structures representing multiple open descriptors on a 
     * single file, but they all point to a single "inode" structure.
     * The "inode" structure contains a great deal of information about the file. As a general 
     * rule, "cdev" structure is useful for writing driver code: 
     */
    cdev_init(&dummy_device_cdev, &fops);
    dummy_device_cdev.owner = THIS_MODULE;
    dummy_device_cdev.ops = &fops;

    /*Adding character device to the system*/
    if((cdev_add(&dummy_device_cdev, dev, 1)) < 0){
        printk(KERN_INFO "Cannot add the device to the system\n");
        goto r_class;
    }

    /*Creating struct class*/
    /* 
     * This will create the struct class for our device driver. 
     * It will create structure under/sys/class/.
     */            
    if((dev_class = class_create(THIS_MODULE, "dummy_device_class")) == NULL){
        printk(KERN_INFO "Cannot create the struct class\n");
        goto r_class;
    }

    /*Creating device*/
    /* 
     * This function can be used by char device classes. A struct device 
     * will be created in "sysfs", registered to the specified class. 
     */
    if((device_create(dev_class, NULL , dev, NULL, "dummy_device_device")) == NULL){
        printk(KERN_INFO "Cannot create the Device 1\n");
        goto r_device;
    }
    printk(KERN_INFO "Device Driver Insert...Done!!!\n");
    return 0;

r_device:
    class_destroy(dev_class);
r_class:
    unregister_chrdev_region(dev,1);
    return -1;
}

void __exit dummy_device_driver_exit(void)
{
    device_destroy(dev_class, dev);
    class_destroy(dev_class);
    cdev_del(&dummy_device_cdev);
    unregister_chrdev_region(dev, 1);
    printk(KERN_INFO "Device Driver Remove...Done!!!\n");
}

module_init(dummy_device_driver_init);
module_exit(dummy_device_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Neelkanth Reddy <www.neelkanth.13@gmail.com>");
MODULE_DESCRIPTION("A simple device driver");
MODULE_VERSION("0:1.0");

neelkanth_surekha#cat Makefile 

obj-m += hello_world_module.o

KDIR = /lib/modules/$(shell uname -r)/build

all:
make -C $(KDIR)  M=$(shell pwd) modules

clean:
make -C $(KDIR)  M=$(shell pwd) clean

Linux Kernel Driver Program:5_Manually_Creating_Device_File

Linux Kernel Driver Program:

5_Manually_Creating_Device_File

neelkanth_surekha#cat hello_world_module.c 

/**********************************************************************
 * After inserting the below kernel module, manually create a device 
 * File using below command:
 *
 * sudo mknod -m 666 /dev/etx_device c 246 0
 ***********************************************************************/


#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>

dev_t dev = 0;

static int __init hello_world_init(void)
{
    /*Allocating Major number*/
    if((alloc_chrdev_region(&dev, 0, 1, "Neelkanth")) <0){
        printk(KERN_INFO "Cannot allocate major number for device\n");
        return -1;
    }
    printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));
    printk(KERN_INFO "Kernel Module Inserted Successfully...\n");
    return 0;
}

void __exit hello_world_exit(void)
{
    unregister_chrdev_region(dev, 1);
    printk(KERN_INFO "Kernel Module Removed Successfully...\n");
}

module_init(hello_world_init);
module_exit(hello_world_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Neelkanth <www.neelkanth.13@gmail.com>");
MODULE_DESCRIPTION("A simple hello world driver");
MODULE_VERSION("1.1");

neelkanth_surekha#cat Makefile 

obj-m += hello_world_module.o

KDIR = /lib/modules/$(shell uname -r)/build

all:
make -C $(KDIR)  M=$(shell pwd) modules

clean:
make -C $(KDIR)  M=$(shell pwd) clean

Linux Kernel Driver Program:4_Dynamically_Allocating_Major_Number

Linux Kernel Driver Program:4_Dynamically_Allocating_Major_Number

neelkanth_surekha#cat hello_world_module.c 

#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>

dev_t dev = 0;

static int __init hello_world_init(void)
{
    /*Allocating Major number*/
    if((alloc_chrdev_region(&dev, 0, 1, "Neelkanth")) <0){
        printk(KERN_INFO "Cannot allocate major number for device 1\n");
        return -1;
    }
    printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));
    printk(KERN_INFO "Kernel Module Inserted Successfully...\n");
    return 0;
}

void __exit hello_world_exit(void)
{
    unregister_chrdev_region(dev, 1);
    printk(KERN_INFO "Kernel Module Removed Successfully...\n");
}

module_init(hello_world_init);
module_exit(hello_world_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Neelkanth <www.neelkanth.13@gmail.com>");
MODULE_DESCRIPTION("A simple hello world driver");
MODULE_VERSION("1.1");

neelkanth_surekha#cat Makefile 

obj-m += hello_world_module.o

KDIR = /lib/modules/$(shell uname -r)/build

all:
make -C $(KDIR)  M=$(shell pwd) modules

clean:
make -C $(KDIR)  M=$(shell pwd) clean