Linuxデバイスドライバ開発 デバイス

デバイス

前回のLinuxデバイスドライバ開発 デバイスクラスからの続き。
デバイスを登録すると/sys/devices/virtual/ 配下で存在が確認できるようになる。
またシンボルが/sys/class/クラス名 配下に張られる。

  1. #include <linux/init.h>  
  2. #include <linux/module.h>  
  3. #include <linux/types.h>          /* dev_t */  
  4. #include <linux/kdev_t.h>         /* MKDEV(), MAJOR() */  
  5. #include <linux/fs.h>             /* register_chrdev_region(), alloc_chrdev_region(), unregister_chrdev() */  
  6. #include <linux/device.h>         /* class_create(), class_unregister(), class_destroy() */  
  7.   
  8. MODULE_LICENSE("GPL v2");  
  9.   
  10. int drv_major = 0;  
  11. int drv_minor = 0;  
  12. int drv_nr_devs = 1;  
  13. struct class *skel_drv_class = NULL;  
  14. struct device *skel_drv_device = NULL;  
  15.   
  16. #define SKEL_DRV_NAME "skel_drv"  
  17.   
  18. static int skel_init(void)  
  19. {  
  20.     dev_t dev = 0;  
  21.     int ret;  
  22.   
  23.     pr_info("%s\n", __FUNCTION__);  
  24.   
  25.     if (drv_major) {  
  26.         /* 指定デバイス番号を登録する */  
  27.         dev = MKDEV(drv_major, drv_minor);  
  28.         ret = register_chrdev_region(dev, drv_nr_devs, SKEL_DRV_NAME);  
  29.     }  
  30.     else {  
  31.         /* デバイス番号を動的に確保する */  
  32.         ret = alloc_chrdev_region(&dev, drv_minor, drv_nr_devs, SKEL_DRV_NAME);  
  33.         drv_major = MAJOR(dev);  
  34.     }  
  35.   
  36.     if (ret < 0) {  
  37.         pr_err("SKEL_DRV: cant't get major %d\n", drv_major);  
  38.     }  
  39.     else {  
  40.         pr_info("SKEL_DRV: char driver major number is %d\n", drv_major);  
  41.     }  
  42.   
  43.     /* デバイスクラスを作成する */  
  44.     skel_drv_class = class_create(THIS_MODULE, SKEL_DRV_NAME);  
  45.     if (IS_ERR(skel_drv_class)) {  
  46.         pr_err("SKEL_DRV: class_create failed\n");  
  47.         goto unregister_region;  
  48.     }  
  49.   
  50.     /* デバイスを作成する */  
  51.     skel_drv_device = device_create(skel_drv_class, NULL, MKDEV(drv_major, drv_minor), NULL, "SKEL_DRV%d", drv_minor);  
  52.     if (IS_ERR(skel_drv_device)) {  
  53.         pr_err("SKEL_DRV: device_create failed\n");  
  54.         goto destroy_class;  
  55.     }  
  56.     else {  
  57.         goto exit;  
  58.     }  
  59.   
  60. destroy_class:  
  61.     class_unregister(skel_drv_class);  
  62.     class_destroy(skel_drv_class);  
  63. unregister_region:  
  64.     unregister_chrdev_region(dev, drv_nr_devs);  
  65. exit:  
  66.     return 0;  
  67. }  
  68.   
  69. static void skel_exit(void)  
  70. {  
  71.     dev_t dev = 0;  
  72.   
  73.     pr_info("%s\n", __FUNCTION__);  
  74.   
  75.     /* デバイスを破棄する */  
  76.     device_destroy(skel_drv_class, MKDEV(drv_major, drv_minor));  
  77.   
  78.     /* デバイスクラスを破棄する */  
  79.     class_unregister(skel_drv_class);  
  80.     class_destroy(skel_drv_class);  
  81.   
  82.     /* デバイス番号の登録を解除する */  
  83.     dev = MKDEV(drv_major, drv_minor);  
  84.     unregister_chrdev_region(dev, drv_nr_devs);  
  85. }  
  86.   
  87. module_init(skel_init);  
  88. module_exit(skel_exit);  

実行確認

$ sudo insmod skel_drv.ko
$ cat /proc/devices | grep skel
246 skel_drv
$ ls -lR /sys/class/ | grep skel
drwxr-xr-x 2 root root 0  2月 14 16:58 skel_drv
/sys/class/skel_drv:
lrwxrwxrwx 1 root root 0  2月 14 16:59 SKEL_DRV0 -> ../../devices/virtual/skel_drv/SKEL_DRV0
$ sudo rmmod skel_drv
$ dmesg | tail
 :
[278044.934071] skel_init
[278044.934074] SKEL_DRV: char driver major number is 246
[278114.560203] skel_exit

ソースコード ダウンロード

目次


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS