自動創建設備節點

使用linux-2.6.30.4。

文件的管理使用的是 sysfs.(由udev製作的文件系統)

 

涉及兩個函數:

virtual_disk_class = class_create(THIS_MODULE, "VirtualDisk");

device_create( virtual_disk_class, NULL, devno, 0, "VirtualDisk");

 

使用需添加頭文件 #include <linux/device.h>

 

說明:

當使用利用udev製作的文件系統時,Linux內核爲我們提供了一組函數,可以用來在模塊加載的時候自動在/dev目錄下創建相應設備節點,並在卸載模塊時刪除該節點。

內核中定義了struct class結構體,一個struct class結構體類型變量對應一個類(有待商榷),內核同時提供了class_create(…)函數,可以用它來創建一個類,這個類存放於sysfs下面,一旦創建好了這個類,再調用device_create(…)函數來在/dev目錄下創建相應的設備節點。這樣,加載模塊的時候,用戶空間中的udev會自動響應device_create(…)函數,去/sysfs下尋找對應的類從而創建設備節點。

 

在linux-2.6.30.4,struct class定義在頭文件include/linux/device.h中,

struct class {
    const char        *name;
    struct module        *owner;

    struct class_attribute        *class_attrs;
    struct device_attribute        *dev_attrs;
    struct kobject            *dev_kobj;

    int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);

    void (*class_release)(struct class *class);
    void (*dev_release)(struct device *dev);

    int (*suspend)(struct device *dev, pm_message_t state);
    int (*resume)(struct device *dev);

    struct dev_pm_ops *pm;
    struct class_private *p;
};

 

class_create(…)頭文件include/linux/device.h中,

#define class_create(owner, name)        /
({                        /
    static struct lock_class_key __key;    /
    __class_create(owner, name, &__key);    /
})

__class_create在/drivers/base/class.c中實現:

struct class *__class_create(struct module *owner, const char *name,
                 struct lock_class_key *key)

 

device_create(…)函數在/drivers/base/core.c中實現:

struct device *device_create(struct class *class, struct device *parent,
                 dev_t devt, void *drvdata, const char *fmt, ...)

 * device_create - creates a device and registers it with sysfs
 * @class: pointer to the struct class that this device should be registered to
 * @parent: pointer to the parent struct device of this new device, if any
 * @devt: the dev_t for the char device to be added
 * @drvdata: the data to be added to the device for callbacks
 * @fmt: string for the device's name

 

使用示例:

virtual_disk_class = class_create(THIS_MODULE, "VirtualDisk");

device_create( virtual_disk_class, NULL, devno, 0, "VirtualDisk");

 

示例程序(一個簡單的字符驅動):

struct class *virtual_disk_class; 	/*by yinhf.*/
/*設備驅動模塊加載函數*/
int VirtualDisk_init(void)
{
  int result;
  dev_t devno = MKDEV(VirtualDisk_major, 0); /*構建設備號*/
  /* 申請設備號*/
  if (VirtualDisk_major)  /* 如果不爲0,則靜態申請*/
    result = register_chrdev_region(devno, 1, "VirtualDisk");
  else  /* 動態申請設備號 */
  {
    result = alloc_chrdev_region(&devno, 0, 1, "VirtualDisk");
    VirtualDisk_major = MAJOR(devno);/* 從申請設備號中得到主設備號 */
  }  
  if (result < 0)
    return result;
    
  /* 動態申請設備結構體的內存*/
  Virtualdisk_devp = kmalloc(sizeof(struct VirtualDisk), GFP_KERNEL);
  if (!Virtualdisk_devp)    /*申請失敗*/
  {
    result =  - ENOMEM;
    goto fail_kmalloc;
  }
  memset(Virtualdisk_devp, 0, sizeof(struct VirtualDisk));/*將內存清零*/
  /*初始化並且添加cdev結構體*/
  VirtualDisk_setup_cdev(Virtualdisk_devp, 0);
//  devfs_mk_cdev(devno, S_IFCHR|S_IRUGO|S_IWUSR, "VirtualDisk");		/*yinhf*/
  printk(KERN_ALERT "Virtualdisk Success/n");
  /* create virtual_disk_class under /sysfs by yinhf.*/
  virtual_disk_class = class_create(THIS_MODULE, "VirtualDisk");
  if(IS_ERR(virtual_disk_class))
  {
    printk("Err: failed in creating virtual_disk_class./n");
    return -1;
  }
  /* register your own device in sysfs, and this will cause udev to create corresponding device node */
  device_create( virtual_disk_class, NULL, devno, 0, "VirtualDisk");
  printk (KERN_INFO "Registered character driver VirtualDisk./n");
  /*end create virtual_disk_class by yinhf.*/
  return 0;
  fail_kmalloc:
  unregister_chrdev_region(devno, 1);
  return result;
}


 

/*模塊卸載函數*/
void VirtualDisk_exit(void)
{
  cdev_del(&Virtualdisk_devp->cdev);   /*註銷cdev*/
  kfree(Virtualdisk_devp);     /*釋放設備結構體內存*/
  device_destroy(virtual_disk_class, MKDEV(VirtualDisk_major, 0));         //delete device node under /dev
  class_destroy(virtual_disk_class);                               //delete class created by us
  unregister_chrdev_region(MKDEV(VirtualDisk_major, 0), 1); /*釋放設備號*/
}

 

參考網址:

http://blog.csdn.net/engerled/archive/2011/02/24/6205722.aspx

發佈了6 篇原創文章 · 獲贊 9 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章