character_device_create.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /* https://github.com/cirosantilli/linux-kernel-module-cheat#automatically-create-character-device-file-on-insmod */
  2. #include <linux/cdev.h>
  3. #include <linux/device.h>
  4. #include <linux/fs.h> /* register_chrdev, unregister_chrdev */
  5. #include <linux/module.h>
  6. #include <linux/seq_file.h> /* seq_read, seq_lseek, single_release */
  7. #define NAME "lkmc_character_device_create"
  8. static int major = -1;
  9. static struct cdev mycdev;
  10. static struct class *myclass = NULL;
  11. static int show(struct seq_file *m, void *v)
  12. {
  13. seq_printf(m, "abcd");
  14. return 0;
  15. }
  16. static int open(struct inode *inode, struct file *file)
  17. {
  18. return single_open(file, show, NULL);
  19. }
  20. static const struct file_operations fops = {
  21. .llseek = seq_lseek,
  22. .open = open,
  23. .owner = THIS_MODULE,
  24. .read = seq_read,
  25. .release = single_release,
  26. };
  27. static void cleanup(int device_created)
  28. {
  29. if (device_created) {
  30. device_destroy(myclass, major);
  31. cdev_del(&mycdev);
  32. }
  33. if (myclass)
  34. class_destroy(myclass);
  35. if (major != -1)
  36. unregister_chrdev_region(major, 1);
  37. }
  38. static int myinit(void)
  39. {
  40. int device_created = 0;
  41. /* cat /proc/devices */
  42. if (alloc_chrdev_region(&major, 0, 1, NAME "_proc") < 0)
  43. goto error;
  44. /* ls /sys/class */
  45. if ((myclass = class_create(THIS_MODULE, NAME "_sys")) == NULL)
  46. goto error;
  47. /* ls /dev/ */
  48. if (device_create(myclass, NULL, major, NULL, NAME "_dev") == NULL)
  49. goto error;
  50. device_created = 1;
  51. cdev_init(&mycdev, &fops);
  52. if (cdev_add(&mycdev, major, 1) == -1)
  53. goto error;
  54. return 0;
  55. error:
  56. cleanup(device_created);
  57. return -1;
  58. }
  59. static void myexit(void)
  60. {
  61. cleanup(1);
  62. }
  63. module_init(myinit)
  64. module_exit(myexit)
  65. MODULE_LICENSE("GPL");