Questions about this topic? Sign up to ask in the talk tab.
LKM/chardev.c
From NetSec
Revision as of 22:45, 24 June 2016 by Null (Talk | contribs) (Created page with "{{code|text= <source lang="c"> #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> #include <linux/fs.h> #include <asm/uacces...")
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> #include <linux/fs.h> #include <asm/uaccess.h> #include <linux/slab.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Dade Murphy"); MODULE_DESCRIPTION("A simple character driver that creates a device that can be written to and read from."); MODULE_VERSION("0.1"); /* * To test this module, load it and try: * $ cat /dev/mod0 * $ cat filename.txt > /dev/mod0 * $ cat /dev/mod0 * Effectively whatever is sent to the device is stored and returned next time the device is read. * The buffer used is only 50 bytes, but there's no reason you can't increase that. It's written to be overflow-safe. */ //handle parameters for device name static char *devno = "0"; module_param(devno, charp, 0664); MODULE_PARM_DESC(devno, "The device number, e.g. a value of 2 will create /dev/mod2"); //initialize variables used by the driver static int majorNumber; char cur_value[50] = { 'n', 'o', 'n', 'e', '\n', 0 }; static struct class* myModule_class = NULL; static struct device* myModule_device = NULL; static ssize_t recvd = 0; static ssize_t sent = 0; //function prototypes for our file operations struct static int device_open(struct inode *, struct file *); static ssize_t device_read(struct file *, char __user *, size_t, loff_t *); static ssize_t device_write(struct file *, char __user *, size_t, loff_t *); static ssize_t device_release(struct inode *, struct file *); //mapping our custom functions to the file operations in <linux/fs.h> static struct file_operations fops = { .open = device_open, .read = device_read, .write = device_write, .release = device_release, }; //init function: register major number, class and device static int __init myModule_init(void) { char *name = kmalloc(10, GFP_KERNEL); strncpy(name, "mod0", 4); name[3] = devno[0]; name[4] = 0x00; majorNumber = register_chrdev(0, "myModule", &fops); myModule_class = class_create(THIS_MODULE, "myModule"); myModule_device = device_create(myModule_class, NULL, MKDEV(majorNumber, 0), NULL, name); printk(KERN_INFO "Hello, my major number is %d.\n", majorNumber); return 0; } //exit function - destroy device and clean up static void __exit myModule_exit(void) { device_destroy(myModule_class, MKDEV(majorNumber, 0)); class_unregister(myModule_class); class_destroy(myModule_class); unregister_chrdev(majorNumber, "myModule"); printk(KERN_INFO "This device, class and major number were successfully destroyed.\n"); } //file operation functions begin here static int device_open(struct inode *inode_pointer, struct file *file_pointer) { printk(KERN_INFO "The device was just opened!\n"); return 0; } static ssize_t device_release(struct inode *inode_pointer, struct file *file_pointer) { printk(KERN_INFO "The device was just released!\n"); return 0; } static ssize_t device_read(struct file *file_ptr, char __user *usr_ptr, size_t size_ptr, loff_t *offset_ptr) { printk(KERN_INFO "The device was just read! Sending it some data....\n"); int error = copy_to_user(usr_ptr, cur_value, strlen(cur_value)); ssize_t bytes = size_ptr - (*offset_ptr); (*offset_ptr) += bytes; return bytes; } static ssize_t device_write(struct file *file_ptr, char __user *usr_ptr, size_t size_ptr, loff_t *offset_ptr) { static char buf[50] = {0}; //strncpy(buf, usr_ptr, 50); copy_from_user(buf, usr_ptr, 50); buf[49] = 0x00; printk(KERN_INFO "The device was just written!\n"); printk(KERN_INFO "The message was: %s", buf); strncpy(cur_value, buf, 50); ssize_t bytes = size_ptr - (*offset_ptr); (*offset_ptr) += bytes; return bytes; } module_init(myModule_init); module_exit(myModule_exit); |