Advertisement
xosski

Hello_char_device

Jan 9th, 2025
16
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.13 KB | None | 0 0
  1. #include <linux/cdev.h>
  2. #include <linux/fs.h>
  3. #include <linux/init.h>
  4. #include <linux/module.h>
  5. #include <linux/printk.h>
  6. #include <linux/stat.h>
  7. #include <linux/timekeeping.h>
  8. #include <linux/uaccess.h>
  9. #include <linux/utsname.h>
  10.  
  11. static char *who = "Master"; // Module parameter for customization
  12. module_param(who, charp, S_IRUGO | S_IWUSR); // Read/Write access to `who`
  13.  
  14. static ssize_t hello_write(struct file *file, const char __user *buf,
  15. size_t count, loff_t *ppos);
  16. static ssize_t hello_read(struct file *file, char __user *buf, size_t count,
  17. loff_t *ppos);
  18. static long hello_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
  19.  
  20. // Buffer for storing data
  21. static void *hello_buf;
  22. static int hello_bufsize = 8192; // Default buffer size
  23. static int hello_count = 1; // Number of devices
  24. static dev_t hello_dev; // Device number
  25. static struct cdev hello_cdev; // Character device structure
  26. static struct file_operations hello_fops = {.owner = THIS_MODULE,
  27. .read = hello_read,
  28. .write = hello_write,
  29. .unlocked_ioctl = hello_ioctl};
  30.  
  31. // Initialize the module
  32. static int __init hello_init(void) {
  33. int err;
  34.  
  35. // Dynamically allocate memory for buffer
  36. hello_buf = kzalloc(hello_bufsize, GFP_KERNEL);
  37. if (!hello_buf) {
  38. pr_err("Failed to allocate buffer\n");
  39. err = -ENOMEM;
  40. goto err_exit;
  41. }
  42.  
  43. // Register device region
  44. if (alloc_chrdev_region(&hello_dev, 0, hello_count, "hello")) {
  45. pr_err("Failed to allocate char device region\n");
  46. err = -ENODEV;
  47. goto err_free_buf;
  48. }
  49.  
  50. // Initialize and add the character device
  51. cdev_init(&hello_cdev, &hello_fops);
  52. if (cdev_add(&hello_cdev, hello_dev, hello_count)) {
  53. pr_err("Failed to add cdev\n");
  54. err = -ENODEV;
  55. goto err_dev_unregister;
  56. }
  57.  
  58. pr_info("Hello major number: %d\n", MAJOR(hello_dev));
  59. return 0;
  60.  
  61. err_dev_unregister:
  62. unregister_chrdev_region(hello_dev, hello_count);
  63. err_free_buf:
  64. kfree(hello_buf);
  65. err_exit:
  66. return err;
  67. }
  68.  
  69. // Cleanup the module
  70. static void __exit hello_exit(void) {
  71. cdev_del(&hello_cdev);
  72. unregister_chrdev_region(hello_dev, hello_count);
  73. kfree(hello_buf);
  74. pr_info("Hello module unloaded\n");
  75. }
  76.  
  77. // Read from the device
  78. static ssize_t hello_read(struct file *file, char __user *buf, size_t count,
  79. loff_t *ppos) {
  80. int ret;
  81.  
  82. // Check if requested count is within the buffer size
  83. if (*ppos >= hello_bufsize)
  84. return 0; // No more data to read
  85.  
  86. // Adjust count to not exceed the buffer size
  87. if (*ppos + count > hello_bufsize)
  88. count = hello_bufsize - *ppos;
  89.  
  90. // Copy data from kernel space to user space
  91. ret = copy_to_user(buf, hello_buf + *ppos, count);
  92. if (ret == 0) {
  93. *ppos += count; // Update file position
  94. return count;
  95. } else {
  96. pr_err("Failed to read data\n");
  97. return -EFAULT;
  98. }
  99. }
  100.  
  101. // Write to the device
  102. static ssize_t hello_write(struct file *file, const char __user *buf,
  103. size_t count, loff_t *ppos) {
  104. int ret;
  105.  
  106. // Check if requested count exceeds the buffer size
  107. if (*ppos >= hello_bufsize)
  108. return -ENOMEM; // No more space to write
  109.  
  110. // Adjust count to prevent overflow
  111. if (*ppos + count > hello_bufsize)
  112. count = hello_bufsize - *ppos;
  113.  
  114. // Copy data from user space to kernel space
  115. ret = copy_from_user(hello_buf + *ppos, buf, count);
  116. if (ret == 0) {
  117. *ppos += count; // Update file position
  118. return count;
  119. } else {
  120. pr_err("Failed to write data\n");
  121. return -EFAULT;
  122. }
  123. }
  124.  
  125. // IOCTL handler (Not implemented yet)
  126. static long hello_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
  127. // Handle custom IOCTL commands here
  128. pr_info("IOCTL command received: %u\n", cmd);
  129. return 0;
  130. }
  131.  
  132. module_init(hello_init);
  133. module_exit(hello_exit);
  134.  
  135. MODULE_DESCRIPTION("A simple Linux driver with read/write functionality");
  136. MODULE_AUTHOR("Xosski");
  137. MODULE_LICENSE("GPL");
  138. MODULE_VERSION("1.0");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement