#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
static DEFINE_MUTEX(mutexIoctl);
//Mutex for unlocked_ioctl
static unsigned char* chpBuf = NULL;
//Device buffer pointer
static int memOpen(struct inode *inp, struct file *fp);
static int memRel(struct inode *inp, struct file *fp);
static ssize_t memRead(struct file *fp, unsigned char *chpOut, size_t sztCount, loff_t *loftPos);
static ssize_t memWrite(struct file *fp, const unsigned char __user *chpIn, size_t sztCount, loff_t *loftPos);
static long memIoctl(struct file *fp, unsigned int iNum, unsigned long iParam);
//Device callback functions
static struct file_operations fileOpers;
static bool bFlag = false;
//Custom device mutex
static int __init kernmodule_init(void)
{
void *vpErr;
//Error pointer
fileOpers.read = memRead;
fileOpers.write = memWrite;
fileOpers.open = memOpen;
fileOpers.release = memRel;
fileOpers.unlocked_ioctl = memIoctl;
//Allocate callback functions
if(register_chrdev(200, "kernmodule", &fileOpers) < 0)
return -EIO;
//Register character device (major = 200, device name = kernmodule)
chpBuf = kmalloc(32, GFP_USER);
if(IS_ERR(vpErr = chpBuf))
return -ENOMEM;
memset(chpBuf, 0, 32);
//Allocate memory area for device buffer
}
static void __exit kernmodule_exit(void)
{
unregister_chrdev(200, "kernmodule");
//Unregister character device
if(chpBuf)
kfree(chpBuf);
}
static int memOpen(struct inode *inp, struct file *fp){
//Device file open
if(bFlag)
return -EBUSY;
bFlag = true;
return 0;
}
static int memRel(struct inode *inp, struct file *fp){
//Device file release
bFlag = false;
return 0;
}
static ssize_t memRead(struct file *fp, unsigned char __user *chpOut, size_t sztCount, loff_t *loftPos){
//read() from device file
if(sztCount > 32)
return -1;
if(bFlag)
copy_to_user(chpOut, chpBuf, sztCount);
return sztCount;
}
static ssize_t memWrite(struct file *fp, const unsigned char __user *chpIn, size_t sztCount, loff_t *loftPos){
//write() to device file
if(sztCount > 32)
return -1;
if(bFlag)
copy_from_user(chpBuf, chpIn, sztCount);
return sztCount;
}
static long memIoctl(struct file *fp, unsigned int uiNum, unsigned long ulParam)
{
int iIter = 0;
mutex_lock(&mutexIoctl);
//ioctl Routine(User-level application can access with ioctl() function)
mutex_unlock(&mutexIoctl);
return 0;
}
//unlocked_ioctl : normal ioctl was deprecated
module_init(kernmodule_init);
module_exit(kernmodule_exit);