character_device.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /*
  2. Allows us to create device files with given file operations with mknod c X.
  3. Usage:
  4. /character_device.sh
  5. The major number determines which module owns the device file.
  6. minor is to differentiate between multiple instances of the device,
  7. e.g. two NVIDIA GPUs using the same kernel module.
  8. We ask the kernel to automatically allocate a major number for us to avoid
  9. conlicts with other devices.
  10. Then we need to check /proc/devices to find out the assigned number,
  11. and use that for the mknod.
  12. - https://unix.stackexchange.com/questions/37829/understanding-character-device-or-character-special-files/371758#371758
  13. */
  14. #include <linux/fs.h> /* register_chrdev, unregister_chrdev */
  15. #include <linux/module.h>
  16. #include <linux/seq_file.h> /* seq_read, seq_lseek, single_release */
  17. #define NAME "lkmc_character_device"
  18. static int major;
  19. static int show(struct seq_file *m, void *v)
  20. {
  21. seq_printf(m, "abcd");
  22. return 0;
  23. }
  24. static int open(struct inode *inode, struct file *file)
  25. {
  26. return single_open(file, show, NULL);
  27. }
  28. static const struct file_operations fops = {
  29. .llseek = seq_lseek,
  30. .open = open,
  31. .owner = THIS_MODULE,
  32. .read = seq_read,
  33. .release = single_release,
  34. };
  35. static int myinit(void)
  36. {
  37. major = register_chrdev(0, NAME, &fops);
  38. return 0;
  39. }
  40. static void myexit(void)
  41. {
  42. unregister_chrdev(major, NAME);
  43. }
  44. module_init(myinit)
  45. module_exit(myexit)
  46. MODULE_LICENSE("GPL");