Advertisement
Guest User

Untitled

a guest
Jul 17th, 2019
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.70 KB | None | 0 0
  1. #include <linux/kernel.h>
  2. #include <linux/init.h>
  3. #include <linux/module.h>
  4. #include <linux/moduleparam.h>
  5. #include <linux/kdev_t.h>
  6. #include <linux/fs.h>
  7. #include <linux/cdev.h>
  8. #include <linux/device.h>
  9. #include<linux/slab.h>                 //kmalloc()
  10. #include<linux/uaccess.h>              //copy_to/from_user()
  11. #include <linux/proc_fs.h>
  12. #include <linux/string.h>
  13. #include <linux/spinlock.h>
  14.  
  15. //uno spinlock per scrivere sul fileA
  16. static spinlock_t spinlock_fileA;
  17.  
  18.  
  19.  
  20. #define mem_size        2048
  21.  
  22. dev_t dev = 0;
  23. //uint8_t *kernel_buffer;
  24.  
  25. static int device_file_major_number = 0;
  26. static const char device_name[] = "Simple-driver";
  27. static short  size_of_message;              ///< Used to remember the size of the string stored
  28.  
  29. static int __init my_init_driver(void);
  30. static void __exit my_exit_driver(void);
  31. static int my_open(struct inode *inode, struct file *file);
  32. static int my_release(struct inode *inode, struct file *file);
  33. static ssize_t my_read(struct file *filp, char __user *buf, size_t len,loff_t * off);
  34. static ssize_t my_write(struct file *filp, const char *buf, size_t len, loff_t * off);
  35. static loff_t my_llseek(struct file *filp, loff_t off, int whence);
  36.  
  37. static char* getFilenameAFromFilenameB(char* filenameB);
  38.  
  39.  
  40.         //loff_t pos = 0;
  41.  
  42. struct my_device_data {
  43.     struct cdev cdev;
  44.     /* my data starts here */
  45.     char* kernel_buffer;
  46.     loff_t offset;
  47.     ssize_t size;
  48.     //spinlock per scrivere sullo stesso kernel buffer in concorrenza
  49.     spinlock_t spinlock_kbuffer;
  50.     int flag;
  51.  
  52.     //...
  53. };
  54.  
  55.  
  56. //MOUDLE PARAM
  57. static char* dirA = "/home/valerio/Documents/dirA/";// directory di A
  58. module_param(dirA,charp,0660);
  59.  
  60. static char* dirB = "/home/valerio/Documents/dirB/";// directory di B
  61. module_param(dirB,charp,0660);
  62.  
  63. static struct file_operations fops =
  64. {
  65.         .owner          = THIS_MODULE,
  66.         .read           = my_read,
  67.         .write          = my_write,
  68.         .open           = my_open,
  69.         .release        = my_release,
  70.         .llseek         = my_llseek,
  71. };
  72.  
  73.  
  74. struct file *file_open(const char *path, int flags, int rights)
  75. {
  76.     struct file *filp = NULL;
  77.     mm_segment_t oldfs;
  78.     int err = 0;
  79.  
  80.     oldfs = get_fs();
  81.     set_fs(get_ds());
  82.     filp = filp_open(path, flags, rights);
  83.     set_fs(oldfs);
  84.     if (IS_ERR(filp)) {
  85.         err = PTR_ERR(filp);
  86.         return NULL;
  87.     }
  88.     return filp;
  89. }
  90. void file_close(struct file *file)
  91. {
  92.     filp_close(file, NULL);
  93. }
  94.  
  95. static int my_open(struct inode *inode, struct file *file)
  96. {
  97.         char* dentry_inode;
  98.         struct file* fileA;
  99.         ssize_t size_fileA;
  100.         loff_t my_offset=0;
  101.         //controllare i flag
  102.         struct my_device_data *my_data;
  103.  
  104.         /* struct my_device_data *my_data;
  105.  
  106.         my_data = container_of(inode->i_cdev, struct my_device_data, cdev);
  107.  
  108.         //Creating Physical memory
  109.         if((my_data->myKernelBuffer = kmalloc(mem_size , GFP_KERNEL)) == 0){
  110.             printk(KERN_INFO "Cannot allocate memory in kernel\n");
  111.             return -1;
  112.         }
  113.         file->private_data = my_data;
  114.         */
  115.         //logica del check se esiste un file in dirA
  116.        
  117.         if ((dentry_inode=getFilenameAFromFilenameB(file->f_path.dentry->d_iname))==NULL)
  118.             {
  119.                 printk("errore nella open dalla directoryA\n");
  120.                 return -1;
  121.             }
  122.        
  123.         printk("provo a fare il lock di spinlock fileA\n");
  124.         spin_lock(&spinlock_fileA);
  125.         printk("finito di fare lock di spinlock fileA\n");
  126.         fileA=file_open(dentry_inode,O_RDWR,0);
  127.         if (fileA ==NULL) {
  128.                 //non abbimao trovato il file in dirA
  129.             printk (KERN_INFO "non posso aprire il file A\n");
  130.             return -1;
  131.         }
  132.         size_fileA=fileA->f_path.dentry->d_inode->i_size;
  133.         printk("info: size file A %d\n",size_fileA);
  134.         /* if (size_fileA>mem_size){
  135.             printk("fileA troppo grande");
  136.             return -1;
  137.         } */
  138.         if ((my_data=kzalloc(sizeof(struct my_device_data),GFP_KERNEL))==NULL){
  139.             printk("fallita la kmalloc\n");
  140.             return -1;
  141.         }
  142.         if ((my_data->kernel_buffer=kzalloc(mem_size,GFP_KERNEL))==NULL){
  143.             printk("fallita la kzalloc\n");
  144.             return -1;
  145.         }
  146.  
  147.         kernel_read(fileA,my_data->kernel_buffer,size_fileA,&my_offset);
  148.         my_data->offset=0;
  149.         my_data->size=mem_size;
  150.         spin_lock_init(&(my_data->spinlock_kbuffer));
  151.         my_data->flag=(file->f_flags & O_ACCMODE);
  152.         file->private_data=my_data;
  153.  
  154.         file_close(fileA);
  155.        
  156.         /* if (size_fileA!=my_offset){
  157.             printk("non è stato letto tutto il file\n");
  158.             spin_unlock(&spinlock_fileA);
  159.             return -1;
  160.         } */
  161.        
  162.         spin_unlock(&spinlock_fileA);
  163.  
  164.  
  165.         //abbiamo trovato il file in dirA
  166.        
  167.         printk(KERN_INFO "Device File Opened...!!!\n");
  168.         return 0;
  169.  
  170. }
  171.  
  172.  
  173.  
  174. static char* getFilenameAFromFilenameB(char* filenameB){
  175.         char* dentry_inode = kzalloc(strlen(dirA)+strlen(filenameB)+1 , GFP_KERNEL);
  176.         if(dentry_inode==NULL){
  177.             printk(KERN_INFO "Cannot allocate memory in kernel\n");
  178.             return NULL;
  179.         }
  180.  
  181.         strcpy(dentry_inode,dirA);
  182.         strcpy(dentry_inode+strlen(dirA),filenameB);
  183.         return dentry_inode;
  184. }
  185.  
  186. static int my_release(struct inode *inode, struct file *file)
  187. {      
  188.         //questo devo modificarlo con llseek
  189.         //pos=0;
  190.         struct my_device_data *my_data;
  191.         my_data = (struct my_device_data *) file->private_data;
  192.         if (my_data->flag == O_RDONLY)
  193.             return 0;
  194.         ssize_t len=my_data->size;
  195.         //metto l'offset a zero perchè faccio il fire di tutto il kernel buffer sul file
  196.         loff_t off=0;
  197.         char* dentry_inode;
  198.         struct file* fileA;
  199.  
  200.         if ((dentry_inode=getFilenameAFromFilenameB(file->f_path.dentry->d_iname))==NULL)
  201.             {
  202.                 printk("errore nella open dalla directoryA");
  203.                 return -1;
  204.             }
  205.         spin_lock(&spinlock_fileA);
  206.         fileA=file_open(dentry_inode,O_RDWR,0);
  207.         if (fileA ==NULL) {
  208.                 //non abbimao trovato il file in dirA
  209.             printk (KERN_INFO "non posso aprire il file A\n");
  210.             return -EPIPE;
  211.         }
  212.         printk("faccio la release del kernel buffer: %s",my_data->kernel_buffer);
  213.         kernel_write(fileA, my_data->kernel_buffer, mem_size, &off);
  214.         file_close(fileA);
  215.         spin_unlock(&spinlock_fileA);
  216.  
  217.         printk(KERN_INFO "Device File Closed...!!!\n");
  218.         return 0;
  219. }
  220.  
  221. static ssize_t my_read(struct file *filp, char __user *buf, size_t size, loff_t *off)
  222. {
  223.     //controllare se con la read devo spostare anche l'offset
  224.     struct my_device_data *my_data;
  225.     int error_count;
  226.     ssize_t len;
  227.  
  228.     my_data = (struct my_device_data *) filp->private_data;
  229.  
  230.     if (my_data->flag==O_WRONLY){
  231.         printk("il file era wronly, non puoi leggere\n");
  232.         return -EFAULT;
  233.     }
  234.  
  235.     len = min(my_data->size - *off, size);
  236.     spin_lock(&(my_data->spinlock_kbuffer));
  237.     if ((error_count=copy_to_user(buf, my_data->kernel_buffer + *off, len))!=0){
  238.             printk(KERN_INFO "EBBChar: Failed to send %d characters to the user\n", error_count);
  239.             return -EFAULT;
  240.  
  241.     }  
  242.     *off=*off+len;  
  243.     spin_unlock(&(my_data->spinlock_kbuffer));
  244.  
  245.     return len;
  246.  
  247. }
  248.  
  249. static ssize_t my_read2(struct file *filp, char __user *buf, size_t size, loff_t *off)
  250. {
  251.        
  252.         //struct my_device_data *my_data;
  253.  
  254.         //my_data = (struct my_device_data *) filp->private_data;
  255.  
  256.         //char* kernel_buffer=my_data->myKernelBuffer;
  257.         //loff_t pos=my_data->offset;
  258.  
  259.         int i;
  260.         //void* data;  //Needs to be a kernel pointer, not userspace pointer
  261.         int block_count; //Set me to something
  262.         int block_size; //Set me to something
  263.         int error_count;
  264.         //mm_segment_t old_fs;
  265.         //old_fs = get_fs();  //Save the current FS segment
  266.         //set_fs(get_ds());
  267.         char* filenameA;
  268.         if ((filenameA=getFilenameAFromFilenameB(filp->f_path.dentry->d_iname))==NULL){
  269.                 printk("problema nel trovare il fileA\n");
  270.                 return -1;
  271.         }
  272.         struct file* fileA=file_open(filenameA, O_RDWR, 0);
  273.         if (fileA ==NULL) {
  274.                 //non abbimao trovato il file in dirA
  275.             printk (KERN_INFO "non posso aprire il file A\n");
  276.             return -1;
  277.         }
  278.  
  279.         if(fileA){
  280.             //fileA->f_pos=0;
  281.                 //block_size=fileA->f_path.dentry->d_inode->i_size;
  282.                 //printk("la size del file A è %d",block_size);
  283.  
  284.  
  285.             /*for(i=0; i < block_count ; i++){
  286.  
  287.                 kernel_buffer=<somewhere>+block_count*i //Wherever your data is
  288.                 if(kernel_buffer==NULL){
  289.                     continue;
  290.                 }
  291.                 vfs_write(fileA, kernel_buffer, block_size, &pos);
  292.                 pos = pos+block_size;
  293.  
  294.             }*/
  295.                 //printk("pos: %d",pos);
  296.                 //printk("pos: %d",pos);
  297.                 //controllare se pos=size
  298.                 //vfs_read(fileA,kernel_buffer,block_size,&pos);
  299.        
  300.         //set_fs(old_fs); //Reset to save FS
  301.  
  302.     //struct my_device_data *my_data = (struct my_device_data *) filp->private_data;
  303.     ssize_t len = min(fileA->f_path.dentry->d_inode->i_size - *off, size);
  304.     loff_t my_offset=*off;
  305.     //da cambiare l'offset, controllare che sono stati scritti tutti i byte
  306.     //kernel_read(fileA,my_data->myKernelBuffer,len,&my_offset);
  307.     fileA->f_pos=0;
  308.     file_close(fileA);
  309.     if (len <= 0)
  310.         return 0;
  311.     //printk("il counter +: %d",fileA->private_data);
  312.  
  313.     /* read data from my_data->buffer to user buffer */
  314.     /*
  315.     if ((error_count=copy_to_user(buf, my_data->myKernelBuffer + *off, len))!=0){
  316.             printk(KERN_INFO "EBBChar: Failed to send %d characters to the user\n", error_count);
  317.             return -EFAULT;
  318.  
  319.     }
  320.  
  321.     *off += len;
  322.     printk(KERN_INFO "EBBChar: Sent %d characters to the user\n", len);
  323.     return len; */
  324.    
  325. }
  326.  
  327.  
  328.  
  329.         /*
  330.         int temp = counter;
  331.  
  332.     if(*off >= len) return 0;
  333.  
  334.     temp = len - *off;
  335.  
  336.     if(len>temp)
  337.     {
  338.         len=temp;
  339.     }
  340.     copy_to_user(buf,kernel_buffer+(*off), len);
  341.  
  342.     //*offp += count;
  343.    
  344.     return len;
  345.         */
  346. }
  347.  
  348. /*void read_file(){
  349.         // Create variables
  350.     struct file *f;
  351.     char buf[128];
  352.     mm_segment_t current_fs;
  353.     int i;
  354.     // Init the buffer with 0
  355.     for(i=0;i<128;i++)
  356.         buf[i] = 0;
  357.     // To see in /var/log/messages that the module is operating
  358.     printk(KERN_INFO "My module is loaded\n");
  359.     // I am using Fedora and for the test I have chosen following file
  360.     // Obviously it is much smaller than the 128 bytes, but hell with it =)
  361.     f = filp_open("/etc/fedora-release", O_RDONLY, 0);
  362.     if(f == NULL)
  363.         printk(KERN_ALERT "filp_open error!!.\n");
  364.     else{
  365.         // Get current segment descriptor
  366.         current_fs = get_fs();
  367.         // Set segment descriptor associated to kernel space
  368.         set_fs(get_ds());
  369.         // Read the file
  370.         f->f_op->read(f, buf, 128, &f->f_pos);
  371.         // Restore segment descriptor
  372.         set_fs( current_fs);
  373.         // See what we read from file
  374.         printk(KERN_INFO "buf:%s\n",buf);
  375.     }
  376.  
  377.  
  378. }*/
  379.  
  380.  
  381. /*void write(){
  382. char* dump_filename; //Set to the file you are targeting
  383. struct file *file;
  384. int i;
  385. void* data;  //Needs to be a kernel pointer, not userspace pointer
  386. int block_count; //Set me to something
  387. int block_size; //Set me to something
  388. loff_t pos = 0;
  389. mm_segment_t old_fs;
  390.  
  391. old_fs = get_fs();  //Save the current FS segment
  392. set_fs(get_ds());
  393.  
  394. file = filp_open(dump_filename, O_WRONLY|O_CREAT, 0644);
  395.  
  396. if(file){
  397.     for(i=0; i < block_count ; i++){
  398.  
  399.         data=<somewhere>+block_count*i //Wherever your data is
  400.         if(data==NULL){
  401.             continue;
  402.         }
  403.         vfs_write(file, data, block_size, &pos);
  404.         pos = pos+block_size;
  405.  
  406.     }
  407.     filp_close(file,NULL);
  408. }
  409. set_fs(old_fs); //Reset to save FS
  410. kfree(dump_filename);
  411. }*/
  412.  
  413. static ssize_t my_write(struct file *filp, const char __user *buf, size_t size, loff_t *off)
  414. {
  415.     //chiedere come si comporta l'offset con l' lseek
  416.     struct my_device_data *my_data;
  417.     int error_count;
  418.     ssize_t len;
  419.  
  420.     my_data = (struct my_device_data *) filp->private_data;
  421.  
  422.     if(my_data->flag==O_RDONLY){
  423.         printk("il file è rdonly\n");
  424.         return -EFAULT;
  425.     }
  426.  
  427.     len = min(my_data->size - *off, size);
  428.  
  429.     if (len <= 0){
  430.         printk("write: sto scrivendo qualcosa di lunghezza pari a 0");
  431.         return 0;
  432.     }
  433.     spin_lock(&(my_data->spinlock_kbuffer));
  434.     if ((error_count=copy_from_user(my_data->kernel_buffer + *off,buf,len))!=0){
  435.             printk(KERN_INFO "EBBChar: Failed to send %d characters to the kernel\n", error_count);
  436.             return -EFAULT;
  437.  
  438.     }
  439.  
  440.     my_data->size=len;  
  441.     spin_unlock(&(my_data->spinlock_kbuffer));
  442.  
  443.     return len;
  444.  
  445. }
  446.  
  447. loff_t my_llseek(struct file *filp, loff_t off, int whence){
  448.     printk("hello world\n");
  449.     struct my_device_data *my_data = (struct my_device_data *) filp->private_data;
  450.   loff_t newpos;
  451.  
  452.   switch(whence) {
  453.    case 0: /* SEEK_SET */
  454.     newpos = off;
  455.     break;
  456.  
  457.    case 1: /* SEEK_CUR */
  458.     newpos = filp->f_pos + off;
  459.     break;
  460.  
  461.    case 2: /* SEEK_END */
  462.     newpos = my_data->size + off;
  463.     break;
  464.  
  465.    default: /* can't happen */
  466.     return -EINVAL;
  467.   }
  468.   if (newpos<0) return -EINVAL;
  469.   filp->f_pos = newpos;
  470.   my_data->offset=newpos;
  471.   return newpos;
  472. }
  473.  
  474.  
  475. static ssize_t my_write2(struct file *filp, const char __user *buf, size_t size, loff_t *off)
  476. {
  477.     printk("info write: size %d offset %d",size,*off);
  478.         int counter;
  479.  
  480.         printk("inizio la write\n");
  481.         //printk("buffer user: %s, size= %d\n",buf,len);
  482.         //printk("buffer kernel: %s\n",kernel_buffer);
  483.         //copy_from_user(kernel_buffer, buf+(*off), len);
  484.  
  485.         char* filenameA;
  486.         if ((filenameA=getFilenameAFromFilenameB(filp->f_path.dentry->d_iname))==NULL){
  487.                 printk("problema nel trovare il fileA\n");
  488.                 return -1;
  489.         }
  490.         struct file* fileA=file_open(filenameA, O_RDWR, 0);
  491.         if (fileA ==NULL) {
  492.                 //non abbimao trovato il file in dirA
  493.             printk (KERN_INFO "non posso aprire il file A\n");
  494.             return -1;
  495.         }
  496.         printk("write: size file %d",fileA->f_path.dentry->d_inode->i_size);
  497.        
  498.         fileA->f_pos=0;
  499.        
  500.         struct my_device_data *my_data = (struct my_device_data *) filp->private_data;
  501.         ssize_t len = min(fileA->f_path.dentry->d_inode->i_size - *off, size);
  502.  
  503.     if (len <= 0){
  504.         printk("write: sto scrivendo qualcosa di lunghezza pari a 0");
  505.         return 0;
  506.     }
  507.  
  508.     /* read data from user buffer to my_data->buffer */
  509.     if ((counter=copy_from_user(my_data->kernel_buffer + *off, buf, len))!=0){
  510.         printk("non ho scritto %d bytes",counter);
  511.         return -EFAULT;
  512.  
  513.     }
  514.     loff_t my_offset=*off;
  515.     kernel_write(fileA, my_data->kernel_buffer, len, &my_offset);
  516.     printk("write: ho scritto %d byte\n",len);
  517.     *off += len;
  518.     fileA->f_pos=0;
  519.         file_close(fileA);
  520.  
  521.     return len;
  522.  
  523.  
  524.        
  525. }
  526.  
  527. static int register_device(void)
  528. {
  529.     spin_lock_init(&spinlock_fileA);
  530.         int result = 0;
  531.  
  532.         printk(KERN_INFO "Simple-driver: register_device() is called.\n" );
  533.  
  534.         result = register_chrdev( 0, device_name, &fops );
  535.  
  536.         if( result < 0 )
  537.         {
  538.             printk( KERN_INFO "Simple-driver:  can\'t register character device with errorcode = %i\n", result );
  539.             return result;
  540.         }
  541.  
  542.         device_file_major_number = result;
  543.         printk("Simple-driver: registered character device with major number = %i and minor numbers from 0 to 255\n", device_file_major_number );
  544.         return 0;
  545. }
  546.  
  547. void unregister_device(void)
  548. {
  549.     printk( KERN_NOTICE "Simple-driver: unregister_device() is called\n" );
  550.     if(device_file_major_number != 0)
  551.     {
  552.         unregister_chrdev(device_file_major_number, device_name);
  553.     }
  554. }
  555.  
  556. static int __init my_init_driver(void)
  557. {
  558.         return register_device();
  559.        
  560.  
  561.         /*
  562.         //Allocating Major number
  563.         if((alloc_chrdev_region(&dev, 0, 1, "my_dev")) <0){
  564.                 printk(KERN_INFO "Cannot allocate major number\n");
  565.                 return -1;
  566.         }
  567.         printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));
  568.  
  569.         //Creating cdev structure
  570.         cdev_init(&etx_cdev,&fops);
  571.  
  572.         //Adding character device to the system
  573.         if((cdev_add(&etx_cdev,dev,1)) < 0){
  574.             printk(KERN_INFO "Cannot add the device to the system\n");
  575.             goto r_class;
  576.         }
  577.  
  578.         //Creating struct class
  579.         if((dev_class = class_create(THIS_MODULE,"my_class")) == NULL){
  580.             printk(KERN_INFO "Cannot create the struct class\n");
  581.             goto r_class;
  582.         }
  583.  
  584.         //Creating device
  585.         if((device_create(dev_class,NULL,dev,NULL,"etx_device")) == NULL){
  586.             printk(KERN_INFO "Cannot create the Device 1\n");
  587.             goto r_device;
  588.         }
  589.         printk(KERN_INFO "Device Driver Insert...Done!!!\n");
  590.     return 0;
  591.  
  592. r_device:
  593.         class_destroy(dev_class);
  594. r_class:
  595.         unregister_chrdev_region(dev,1);
  596.         return -1;
  597. */
  598. }
  599.  
  600.  
  601. void __exit my_exit_driver(void)
  602. {
  603.         unregister_device();
  604.         /*
  605.         device_destroy(dev_class,dev);
  606.         class_destroy(dev_class);
  607.         cdev_del(&etx_cdev);
  608.         unregister_chrdev_region(dev, 1);
  609.     printk(KERN_INFO "Device Driver Remove...Done!!!\n");
  610.     */
  611. }
  612.  
  613. module_init(my_init_driver);
  614. module_exit(my_exit_driver);
  615.  
  616. MODULE_LICENSE("GPL");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement