Follow by Email

Total Pageviews

Tuesday, December 25, 2012

Steps to add Linux Character Device Driver


Linux Device driver

Hi we will learn step to add character device driver to Linux


1)      Create Device in /dev
$mknod  /dev/mydev c 200 10

  200- major number ->Driver Identifier
   10-minor number->Device identifier

2)      Change permission if  necessary
$chmod  xxx /dev/mydev

3)      Write Device driver Program

#include <generated/autoconf.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

char data[1024];
int mydev_open(struct inode *inode, struct file *filp)
{
   printk(KERN_ALERT "Entering mydev_open\n");
   return 0;
}
ssize_t mydev_read(struct file *filp, char __user *buf, size_t count,
                loff_t *f_pos)
{
   printk(KERN_ALERT "Entering mydev_read\n");
   copy_to_user(buf, data, count);
   return count;
}
ssize_t mydev_write(struct file *filp, const char __user *buf, size_t count,
                loff_t *f_pos)
{
   printk(KERN_ALERT "Entering mydev_write\n");
   copy_from_user(data, buf, count);
   return count;
}
loff_t mydev_llseek(struct file *filp, loff_t off, int whence)
{
   printk(KERN_ALERT "Entering mydev_llseek\n");
   return 0;
}
int mydev_release(struct inode *inode, struct file *filp)
{
   printk(KERN_ALERT "Entering mydev_release\n");
        return 0;
}
struct file_operations mydev_ops = {
   .owner = THIS_MODULE,
   .open = mydev_open,
   .read = mydev_read, 
   .write = mydev_write,
   .llseek = mydev_llseek,
   .release = mydev_release,
};

dev_t devno;
struct cdev cdev;
int mydev_init(void) {
   int res, err;
   int major, minor;
   printk(KERN_ALERT "Starting initialisation\n");

   /* Ask the kernel for a major number */
   res = alloc_chrdev_region(&devno, 10, 1, "mydev");
   if(res < 0) {
         printk(KERN_ALERT "Failed Getting Devno\n");
         return EINVAL;
   }
   major = MAJOR(devno);
   minor = MINOR(devno);
   printk(KERN_ALERT "Got Major No. %d Minor no. %d\n", major, minor);

   /* Tell ther kernel, that these are my functions*/
   cdev_init(&cdev, &mydev_ops);
   err = cdev_add(&cdev, devno, 1);
   if(err) {
         printk(KERN_ALERT "Error in cdev_add \n");
         return EINVAL;
   }
   return 0;
}
void mydev_exit(void ) {
   printk(KERN_ALERT "Finishing: In mydev_exit\n");
   cdev_del(&cdev); 
   unregister_chrdev_region(devno, 1);
}
module_init(mydev_init);
module_exit(mydev_exit);

4)      Write makefile to compile driver program
obj-m += mydev.o
all:
                make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
                #make -C /lib/modules/2.6.39.4/build M=$(PWD) modules
clean:
                #make -C /lib/modules/2.6.39.4/build M=$(PWD) clean
                make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
5)      $make
6)      $insmod  mydev.ko
7)      Write user program using that driver

#include <stdio.h>
#include <fcntl.h>
#include <string.h>
int main() {
                int fd, len;
                char ch[128];

                scanf("%s", ch);
                len = strlen(ch);
                fd = open("/dev/mydev", O_WRONLY);
                printf("Got fd = %d\n", fd);
                write(fd, ch, len -1);
                printf("Got char %s \n", ch);
                close(fd);
                strcpy(ch, "XYZ");
                fd = open("/dev/mydev", O_RDONLY);
                printf("Got fd = %d\n", fd);
                read(fd, ch, len -1 );
                printf("Got char %s \n", ch);
                close(fd);
                return 0;
}
8)       $rmmod mydev 

No comments:

Post a Comment