Created
July 2, 2014 16:22
-
-
Save sunny1304/d78be91129fadca3da8e to your computer and use it in GitHub Desktop.
Very basic char device driver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/init.h> | |
#include <linux/module.h> | |
#include <linux/kernel.h> | |
#include <linux/sched.h> | |
#include <linux/fs.h> | |
#include <linux/cdev.h> | |
#include <linux/semaphore.h> | |
#include <asm/uaccess.h> | |
#define DEVICE_NAME "solidusdevice" | |
//this is our device | |
struct fake_device { | |
char data[100]; | |
struct semaphore sem; | |
}virtual_device; | |
// | |
struct cdev* mcdev; // m stands for my | |
int major_number; | |
int ret; | |
dev_t dev_num; // holds major number given by kernel | |
int device_open(struct inode* inode, struct file* filp) | |
{ | |
if (down_interruptible(&virtual_device.sem) != 0) | |
{ | |
printk(KERN_ALERT "Could not lock the device"); | |
return -1; | |
} | |
printk(KERN_INFO "Opened device"); | |
return 0; | |
} | |
ssize_t device_read(struct file* filp, char* bufStoreData, size_t bufCount, loff_t* curOffset ) | |
{ | |
printk(KERN_INFO "Reading from device"); | |
ret = copy_to_user(bufStoreData, virtual_device.data, bufCount); | |
return ret; | |
} | |
ssize_t device_write(struct file* filp, const char* bufStoreData, size_t bufCount, loff_t* curOffset ) | |
{ | |
printk(KERN_INFO "Writing to device"); | |
ret = copy_from_user(bufStoreData, virtual_device.data, bufCount); | |
return ret; | |
} | |
int device_close(struct inode* inode, struct file* filp) | |
{ | |
up(&virtual_device.sem); | |
printk(KERN_INFO "Device Closed"); | |
return 0; | |
} | |
struct file_operations fops = { | |
.owner = THIS_MODULE, | |
.open = device_open, | |
.release = device_close, | |
.write = device_write, | |
.read = device_read | |
}; | |
static int driver_entry() | |
{ | |
ret = alloc_chrdev_region(&dev_num, 0,1,DEVICE_NAME); | |
if(ret < 0) | |
{ | |
printk(KERN_ALERT "Failed to allocate a major number\n" ); | |
return ret; | |
} | |
major_number = MAJOR(dev_num); | |
printk(KERN_ALERT "Major number is: %d", major_number); | |
mcdev = cdev_alloc(); | |
mcdev-> ops = &fops; | |
mcdev-> owner = THIS_MODULE; | |
ret = cdev_add(mcdev, dev_num, 1); | |
if (ret < 0) | |
{ | |
printk(KERN_ALERT "Unable to add the device to kernel"); | |
return ret; | |
} | |
sema_init(&virtual_device.sem, 1); | |
return 0; | |
} | |
static void driver_exit() | |
{ | |
cdev_del(mcdev); | |
unregister_chrdev_region(dev_num,1); | |
printk(KERN_ALERT "Unloaded module"); | |
} | |
module_init(driver_entry); | |
module_exit(driver_exit); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment