Fakultas Ilmu Komputer UI

Commit 05274182 authored by Ardhi Putra Pratama's avatar Ardhi Putra Pratama
Browse files

renaming, commenting stuffs

parent 14c3c7f2
obj-m += lkm-drivers.o
obj-m += rd_devdr.o
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
......
#include <linux/init.h> // Macros used to mark up functions e.g. __init __exit
#include <linux/module.h> // Core header for loading LKMs into the kernel
#include <linux/device.h> // Header to support the kernel Driver Model
#include <linux/kernel.h> // Contains types, macros, functions for the kernel
#include <linux/fs.h> // Header for the Linux file system support
#include <asm/uaccess.h> // Required for the copy to user function
#define DEVICE_NAME "rdchardrv" ///< The device will appear at /dev/rdchardrv using this value
#define CLASS_NAME "rdc" ///< The device class -- this is a character device driver
MODULE_LICENSE("GPL"); ///< The license type -- this affects available functionality
MODULE_AUTHOR("Ardhi Putra Pratama"); ///< The author -- visible when you use modinfo
MODULE_DESCRIPTION("A simple Linux char driver"); ///< The description -- see modinfo
MODULE_VERSION("0.1"); ///< A version number to inform users
static int majorNumber; ///< Stores the device number -- determined automatically
static char message[256] = {0}; ///< Memory for the string that is passed from userspace
static short size_of_message; ///< Used to remember the size of the string stored
static int numberOpens = 0; ///< Counts the number of times the device is opened
static struct class* classptr = NULL; ///< The device-driver class struct pointer
static struct device* dvcptr = NULL; ///< The device-driver device struct pointer
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#define DEVICE_NAME "rdcdevdr" // /dev/<value>
#define CLASS_NAME "rdc" // The device class
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ardhi Putra Pratama");
MODULE_DESCRIPTION("A simple Linux char driver");
MODULE_VERSION("0.1");
static int majorNumber;
static char message[256] = {0};
static short size_of_message;
static int numberOpens = 0;
static struct class* classptr = NULL;
static struct device* dvcptr = NULL;
// The prototype functions for the character driver
static int dev_open(struct inode *, struct file *);
......@@ -36,16 +36,16 @@ static struct file_operations fops =
};
static int __init rdchardrv_init(void){
printk(KERN_INFO "RD-Char Device: Initializing the RD-Char Device LKM\n");
static int __init rdcdevdr_init(void){
printk(KERN_INFO "RDcdevdr: Initializing the RDcdevdr module\n");
// Try to dynamically allocate a major number for the device -- more difficult but worth it
// Try to dynamically allocate a major number for the device
majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
if (majorNumber<0){
printk(KERN_ALERT "RD-Char Device failed to register a major number\n");
printk(KERN_ALERT "RDcdevdr failed to register a major number\n");
return majorNumber;
}
printk(KERN_INFO "RD-Char Device: registered correctly with major number %d\n", majorNumber);
printk(KERN_INFO "RDcdevdr: registered correctly with major number %d\n", majorNumber);
// Register the device class
classptr = class_create(THIS_MODULE, CLASS_NAME);
......@@ -54,61 +54,47 @@ static int __init rdchardrv_init(void){
printk(KERN_ALERT "Failed to register device class\n");
return PTR_ERR(classptr); // Correct way to return an error on a pointer
}
printk(KERN_INFO "RD-Char Device: device class registered correctly\n");
printk(KERN_INFO "RDcdevdr: device class registered correctly\n");
// Register the device driver
dvcptr = device_create(classptr, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
if (IS_ERR(dvcptr)){ // Clean up if there is an error
class_destroy(classptr); // Repeated code but the alternative is goto statements
if (IS_ERR(dvcptr)){
class_destroy(classptr);
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "Failed to create the device\n");
return PTR_ERR(dvcptr);
}
printk(KERN_INFO "RD-Char Device: device class created correctly\n"); // Made it! device was initialized
// Successfully registered both
printk(KERN_INFO "RDcdevdr: device class created correctly\n");
return 0;
}
static void __exit rdchardrv_exit(void){
static void __exit rdcdevdr_exit(void){
device_destroy(classptr, MKDEV(majorNumber, 0)); // remove the device
class_unregister(classptr); // unregister the device class
class_destroy(classptr); // remove the device class
unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number
printk(KERN_INFO "RD-Char Device: Goodbye from the LKM!\n");
printk(KERN_INFO "RDcdevdr: Goodbye from the LKM!\n");
}
static int dev_open(struct inode *inodep, struct file *filep){
numberOpens++;
printk(KERN_INFO "RD-Char Device: Device has been opened %d time(s)\n", numberOpens);
printk(KERN_INFO "RDcdevdr: Device has been opened %d time(s)\n", numberOpens);
return 0;
}
// static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset){
// int error_count = 0;
// // copy_to_user has the format ( * to, *from, size) and returns 0 on success
// error_count = copy_to_user(buffer, message, size_of_message);
//
// if (error_count==0){ // if true then have success
// printk(KERN_INFO "RD-Char Device: Sent %d characters to the user\n", size_of_message);
// return (size_of_message=0); // clear the position to the start and return 0
// }
// else {
// printk(KERN_INFO "RD-Char Device: Failed to send %d characters to the user\n", error_count);
// return -EFAULT; // Failed -- return a bad address message (i.e. -14)
// }
// }
static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset){
//Always return size_of_message or len bytes, whichever is less
size_t bytesToCopy = len >= size_of_message ? size_of_message: len;
size_t bytesNotCopied = 0;
//If size_of_message == 0, do nothing and return zero.
if(!bytesToCopy) return 0;
bytesNotCopied = copy_to_user(buffer, message, bytesToCopy);
if(bytesToCopy - bytesNotCopied)
printk(KERN_INFO "RD-Char Device: Sent %d characters to the user\n",bytesToCopy - bytesNotCopied);
printk(KERN_INFO "RDcdevdr: Sent %d characters to the user\n",bytesToCopy - bytesNotCopied);
if(bytesNotCopied){
printk(KERN_INFO "RD-Char Device: Failed to send %d characters to the user\n", bytesNotCopied);
printk(KERN_INFO "RDcdevdr: Failed to send %d characters to the user\n", bytesNotCopied);
return -EFAULT;
}
size_of_message = 0;
......@@ -116,36 +102,30 @@ static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *of
}
static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){
/* 14 is the max length of the output of sprintf() below,
and we take one more byte out of maxLen to leave room
for the terminating NULL-character. */
/* 14 "()letters 1234"
* 1 -> terminating NULL
*
*/
const size_t maxLen = 256 - 14 - 1;
size_t bytesToCopy = len >= maxLen ? maxLen: len; //If len is 255 or more, copy only 255 bytes
size_t bytesToCopy = len >= maxLen ? maxLen: len; // only copy as max as possible
size_t bytesNotCopied = 0;
bytesNotCopied = copy_from_user(message, buffer, bytesToCopy);
sprintf(message + bytesToCopy - bytesNotCopied, "(%zu letters)", bytesToCopy - bytesNotCopied);
size_of_message = bytesToCopy - bytesNotCopied + 1;
printk(KERN_INFO "RD-Char Device: Received %zu characters from the user\n", bytesToCopy - bytesNotCopied);
printk(KERN_INFO "RDcdevdr: Received %zu characters from the user\n", bytesToCopy - bytesNotCopied);
if(bytesNotCopied){
printk(KERN_INFO "RD-Char Device: Failed to receive %zu characters, -EFAULT!\n", bytesNotCopied);
printk(KERN_INFO "RDcdevdr: Failed to receive %zu characters, -EFAULT!\n", bytesNotCopied);
return -EFAULT;
}
return bytesToCopy;
}
// static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){
// sprintf(message, "%s(%zu letters)", buffer, len); // appending received string with its length
// size_of_message = strlen(message); // store the length of the stored message
// printk(KERN_INFO "RD-Char Device: Received %zu characters from the user\n", len);
// return len;
// }
static int dev_release(struct inode *inodep, struct file *filep){
printk(KERN_INFO "RD-Char Device: Device successfully closed\n");
printk(KERN_INFO "RDcdevdr: Device successfully closed\n");
return 0;
}
module_init(rdchardrv_init);
module_exit(rdchardrv_exit);
module_init(rdcdevdr_init);
module_exit(rdcdevdr_exit);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment