#include #include #include #include /*for dev_t*/ #include/*for fops*/ #include #include #include/*for user copy*/ MODULE_LICENSE("GPL"); int filep_init(void); void filep_exit(void); /*fops function set*/ ssize_t filep_read (struct file *filep, char __user *buffer, size_t size, loff_t *offset); ssize_t filep_write (struct file *filep, const char __user *buffer, size_t size, loff_t *offset); int filep_open (struct inode *inode, struct file *filep); int filep_release (struct inode *inode, struct file *filep); dev_t filepDev; struct cdev filepCdev; struct file_operations filepFops= { .open=filep_open, .read=filep_read, .write=filep_write, .release=filep_release }; /*module init*/ int filep_init(void) { int status; /*allocate one major and 2 minor numbers*/ status=alloc_chrdev_region(&filepDev,0,2,"filep"); if(0!=status) { printk(KERN_ALERT"alloc_chrdev_region failed\n"); return status; } else { /*init one module for 2 devices*/ cdev_init(&filepCdev,&filepFops); status=cdev_add(&filepCdev,filepDev,2); if(0!=status) { printk(KERN_ALERT"cdev_add failed \n"); filep_exit(); return status; } } printk(KERN_ALERT"inserted filep (%d,%d)\n",MAJOR(filepDev),MINOR(filepDev)); return 0; } void filep_exit(void) { cdev_del(&filepCdev); unregister_chrdev_region(filepDev,2); } /*reasd syscall backend*/ ssize_t filep_read (struct file *filep, char __user *buffer, size_t size, loff_t *offset) { /*fetch device minor number from inode in the file structure pointer*/ int filepMinor=iminor(filep->f_dentry->d_inode); char *message="unrecognized minor numerber\n"; /*decision fork for different minor numbers*/ if(0==filepMinor) { message="this is minor number 0\n"; } else if (1==filepMinor) { message="this is minor number 1\n"; } /*print only once for read from begining of file*/ if(0==*offset) { copy_to_user(buffer,message,sizeof(char)*(strlen(message)+1)); *offset=1; return (sizeof(char)*(strlen(message)+1)); } else { return 0; } } /*pass through write*/ ssize_t filep_write (struct file *filep, const char __user *buffer, size_t size, loff_t *offset) { return size; } int filep_open (struct inode *inode, struct file *filep) { return 0; } int filep_release (struct inode *inode, struct file *filep) { return 0; } module_init(filep_init); module_exit(filep_exit);