Advertisement
Guest User

Untitled

a guest
Jul 2nd, 2015
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.87 KB | None | 0 0
  1. /* Declare what kind of code we want from the header files
  2. Defining __KERNEL__ and MODULE allows us to access kernel-level
  3. code not usually available to userspace programs. */
  4. #undef __KERNEL__
  5. #define __KERNEL__ /* We're part of the kernel */
  6. #undef MODULE
  7. #define MODULE /* Not a permanent part, though. */
  8.  
  9. #include <linux/kernel.h> /* We're doing kernel work */
  10. #include <linux/module.h> /* Specifically, a module */
  11. #include <linux/fs.h> /* for register_chrdev */
  12. #include <asm/uaccess.h> /* for get_user and put_user */
  13. #include <linux/string.h> /* for memset. NOTE - not string.h!*/
  14.  
  15. MODULE_LICENSE("GPL");
  16.  
  17. #define SUCCESS 0
  18. #define DEVICE_RANGE_NAME "char_dev"
  19. #define BUF_LEN 80
  20. #define DEVICE_FILE_NAME "simple_char_dev"
  21.  
  22. struct chardev_info{
  23. spinlock_t lock;
  24. };
  25.  
  26. static int dev_open_flag = 0; /* used to prevent concurent access into the same device */
  27. static struct chardev_info device_info;
  28. static int loc; /* to store the location : where we are in the buffer */
  29.  
  30. static char Message[BUF_LEN]; /* The message the device will give when asked */
  31. static int major; /* device major number */
  32.  
  33. /***************** char device functions *********************/
  34.  
  35. /* process attempts to open the device file */
  36. static int device_open(struct inode *inode, struct file *file)
  37. {
  38. unsigned long flags; // for spinlock
  39. printk("device_open(%p)\n", file);
  40.  
  41. /*
  42. * We don't want to talk to two processes at the same time
  43. */
  44. spin_lock_irqsave(&device_info.lock, flags);
  45. if (dev_open_flag){
  46. spin_unlock_irqrestore(&device_info.lock, flags);
  47. return -EBUSY;
  48. }
  49.  
  50. dev_open_flag++;
  51. spin_unlock_irqrestore(&device_info.lock, flags);
  52.  
  53. return SUCCESS;
  54. }
  55.  
  56. static int device_release(struct inode *inode, struct file *file)
  57. {
  58. unsigned long flags; // for spinlock
  59. printk("device_release(%p,%p)\n", inode, file);
  60.  
  61. /* ready for our next caller */
  62. spin_lock_irqsave(&device_info.lock, flags);
  63. dev_open_flag--;
  64. spin_unlock_irqrestore(&device_info.lock, flags);
  65.  
  66. return SUCCESS;
  67. }
  68.  
  69. /* a process which has already opened
  70. the device file attempts to read from it */
  71. static ssize_t device_read(struct file *file, /* see include/linux/fs.h */
  72. char __user * buffer, /* buffer to be filled with data */
  73. size_t length, /* length of the buffer */
  74. loff_t * offset)
  75. {
  76.  
  77. if(put_user(Message[loc], buffer) != 0){
  78. printk("Error : put_user() failed");
  79. return -EFAULT;
  80. }
  81. printk("device read : %c\n", Message[loc]);
  82. loc = (loc + 1) % strlen(Message);
  83.  
  84. return 1; //sucess in reading one char from Message
  85.  
  86. }
  87.  
  88. /* somebody tries to write into our device file */
  89. static ssize_t
  90. device_write(struct file *file,
  91. const char __user * buffer, size_t length, loff_t * offset)
  92. {
  93. printk("device_write - operation not supported...\n");
  94. return -EINVAL; // invalid argument error
  95. }
  96.  
  97. /************** Module Declarations *****************/
  98.  
  99. /* This structure will hold the functions to be called
  100. * when a process does something to the device we created */
  101. struct file_operations Fops = {
  102. .read = device_read,
  103. .write = device_write,
  104. .open = device_open,
  105. .release = device_release, /* a.k.a. close */
  106. };
  107.  
  108. /* Called when module is loaded.
  109. * Initialize the module - Register the character device */
  110. static int simple_init(void)
  111. {
  112. /* init dev struct*/
  113. memset(&device_info, 0, sizeof(struct chardev_info));
  114. spin_lock_init(&device_info.lock);
  115.  
  116. /* Register a character device. Get newly assigned major num */
  117. major = register_chrdev(0, DEVICE_RANGE_NAME, &Fops /* our own file operations struct */);
  118.  
  119. /*
  120. * Negative values signify an error
  121. */
  122. if (major < 0) {
  123. printk(KERN_ALERT "%s failed with %d\n",
  124. "Sorry, registering the character device ", major);
  125. return major;
  126. }
  127.  
  128. loc = 0; /* initializing the loc parameter to start of Message*/
  129. strcpy(Message, "Itzik Kabessa"); /* setting buffer to my name */
  130. printk("Initialization completed\n");
  131. printk("Registeration is a success. The major device number is %d.\n", major);
  132. printk("If you want to talk to the device driver,\n");
  133. printk("you have to create a device file:\n");
  134. printk("mknod /dev/%s c %d 0\n", DEVICE_FILE_NAME, major);
  135. printk("You can echo/cat to/from the device file.\n");
  136. printk("Dont forget to rm the device file and rmmod when you're done\n");
  137.  
  138. return 0;
  139. }
  140.  
  141. /* Cleanup - unregister the appropriate file from /proc */
  142. static void __exit simple_cleanup(void)
  143. {
  144. /*
  145. * Unregister the device
  146. * should always succeed (didnt used to in older kernel versions)
  147. */
  148. unregister_chrdev(major, DEVICE_RANGE_NAME);
  149. }
  150.  
  151. module_init(simple_init);
  152. module_exit(simple_cleanup);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement