Tuesday, March 15, 2011

Network device driver for my Ubuntu box

I have not updated this post from a long time as currently I am busy with some other system kind of experiments,you can read more about me if you check this link http://biturl.net/tapas

These days I am studying network device drivers for wifi devices.
I am using my laptop for such experiments.The PCI id of device on my laptop is 14e4:4315.

So if interested to develop along we can share some thoughts.
Rest on this blog I am sharing a char device driver if you are interested to know more of my device driver codes you can drop me a mail.Or contact via Skype.


#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <asm/uaccess.h>

#define FIRST_MINOR 0
#define MINOR_CNT 1

static dev_t dev;
static struct cdev c_dev;
static struct class *cl;

static int my_open(struct inode *i, struct file *f)
{
 return 0;
}
static int my_close(struct inode *i, struct file *f)
{
 return 0;
}

static char c = 'A';

static ssize_t my_read(struct file *f, char __user *buf, size_t len, loff_t *off)
{
 if (*off == 0)
 {
  if (copy_to_user(buf, &c, 1))
  {
   return -EFAULT;
  }
  *off += 1;
  return 1;
 }
 else
  return 0;
}
static ssize_t my_write(struct file *f, const char __user *buf, size_t len, loff_t *off)
{
 if (copy_from_user(&c, buf + len - 1, 1))
 {
  return -EFAULT;
 }
 return len;
}

static struct file_operations sri_fops =
{
 .owner = THIS_MODULE,
 .open = my_open,
 .release = my_close,
 .read = my_read,
 .write = my_write
};

int __init init_module()
{
 printk("Hello Universe\n");
 if (alloc_chrdev_region(&dev, FIRST_MINOR, MINOR_CNT, "EMX") < 0)
 {
  return -1;
 }
 printk("Major Nr: %d\n", MAJOR(dev));

 cdev_init(&c_dev, &sri_fops);

 if (cdev_add(&c_dev, dev, MINOR_CNT) == -1)
 {
  unregister_chrdev_region(dev, MINOR_CNT);
  return -1;
 }
 
 if ((cl = class_create(THIS_MODULE, "chardrv")) == NULL)
 {
  cdev_del(&c_dev);
  unregister_chrdev_region(dev, MINOR_CNT);
  return -1;
 }
 if (device_create(cl, NULL, dev, NULL, "mychar%d", 0) == NULL)
 {
  class_destroy(cl);
  cdev_del(&c_dev);
  unregister_chrdev_region(dev, MINOR_CNT);
  return -1;
 }

 return 0;
}

void __exit cleanup_module()
{
 device_destroy(cl, dev);
 class_destroy(cl);
 cdev_del(&c_dev);
 unregister_chrdev_region(dev, MINOR_CNT);
 printk("Bye Universe\n");
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tapas");
MODULE_DESCRIPTION("Test driver");
To test the above driver you will have to create a dummy device on your machine via mknod and statically link this module to the device.
Then you will be able read and write on the device.

Orielly Linux Device Drivers Development 3rd edition has been quite useful for the above code.
If you want to understand the network device section you can read 17th chapter of book and
also Oreilly Linux Network Internals describe this topic in great detail.
If you want to understand how network device driver works you can drop me a mail.

No comments: