Linux /dev 自动创建设备节点

时间:2023-03-08 17:40:47
    1. #include <linux/module.h>
    2. #include <linux/module.h>
    3. #include <linux/kernel.h>
    4. #include <linux/init.h>
    5. #include <linux/fs.h>
    6. #include <linux/cdev.h>
    7. #include <linux/device.h>
    8. #include <asm/uaccess.h>
    9. #define HELLO_MAJOR 250
    10. #define HELLO_MINOR 0
    11. #define NUMBER_OF_DEVICES 2
    12. struct class *hello_class;
    13. static struct cdev cdev;
    14. dev_t devno;
    15. static ssize_t hello_read(struct file *file, char __user *buf, size_t count,
    16. loff_t *ppos)
    17. {
    18. char *str = "hello world";
    19. copy_to_user(buf,str,strlen(str));
    20. *(buf + strlen(str)) = '\n';
    21. return count;
    22. }
    23. static ssize_t hello_open(struct inode *inode,struct file *file)
    24. {
    25. return 0;
    26. }
    27. static const struct file_operations hello_fops = {
    28. .open = hello_open,
    29. .read = hello_read,
    30. .owner = THIS_MODULE,
    31. };
    32. static int __init hello_init(void)
    33. {
    34. int ret;
    35. devno = MKDEV(HELLO_MAJOR,HELLO_MINOR);
    36. if(HELLO_MAJOR){
    37. ret = register_chrdev_region(devno,NUMBER_OF_DEVICES,"chrdev");
    38. }else{
    39. ret = alloc_chrdev_region(&devno, 0, NUMBER_OF_DEVICES, "chrdev");
    40. }
    41. if(ret < 0){
    42. printk("%s register chrdev error\n",__func__);
    43. return ret;
    44. }
    45. hello_class = class_create(THIS_MODULE,"hello_char_calss");
    46. if(IS_ERR(hello_class)){
    47. printk("%s create class error\n",__func__);
    48. return -1;
    49. }
    50. device_create(hello_class, NULL, devno, NULL, "chrdev");
    51. cdev_init(&cdev, &hello_fops);
    52. cdev.owner = THIS_MODULE;
    53. cdev_add(&cdev, devno, NUMBER_OF_DEVICES);
    54. return 0;
    55. }
    56. static void __exit hello_exit(void)
    57. {
    58. printk("%s",__func__);
    59. cdev_del(&cdev);
    60. device_destroy(hello_class,devno);
    61. class_destroy(hello_class);
    62. unregister_chrdev_region(devno,NUMBER_OF_DEVICES);
    63. }
    64. module_init(hello_init);
    65. module_exit(hello_exit);
    66. MODULE_LICENSE("GPL");
    67. MODULE_AUTHOR("oracleloyal@gmail.com");
    68. Makefile 内容
    69. 1 ifeq ($(KERNELRELEASE),)
        2 #KERNEL_DIR:=/home/archermind/zhaoxi/bsw_ww02_2016/kernel/cht
        3 KERNEL_DIR:=/usr/src/linux-headers-3.13.0-32-generic
        4 PWD:=$(shell pwd)
        5 modules:
        6     $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
        7 modules_install:
        8     $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules_install
        9 clean:
       10     rm -rf  .*.cmd *.ko  *.o modules.order  Module.symvers *mod.c
       11     .PHONY: modules modules_install clean
       12 else
       13     modules-objs := my.o
       14     obj-m := my.o
       15 endif

      编译模块安装之后会在/sys/class/看到hello_char_class 以及目录内的chrdev,同时也会在/dev下看到udev为我们建立的节点chrdev.

      测试程序

      1. #include <stdio.h>
      2. #include <fcntl.h>
      3. int main(void)
      4. {
      5. int fd;
      6. int i;
      7. char buf[50];
      8. fd = open("/dev/chrdev",O_RDWR);
      9. if(fd < 0){
      10. printf("can't open dev\n");
      11. return -1;
      12. }
      13. read(fd,buf,11);
      14. printf("%s",buf);
      15. return 0;
      16. }
      17. 测试程序执行后会输出hello world.,