如何自動建立裝置節點

來源:互聯網
上載者:User

標籤:va_list   round   資料   uname   ati   build   lin   更新   程式   

建立裝置檔案的方法:

第一種是使用mknod手工建立:mknod filename type major minor

第二種是自動建立裝置節點:利用udev(mdev)來實現裝置檔案的自動建立,首先應保證支援udev(嵌入式系統用mdev),由busybox配置。

udev介紹

udev 運行在使用者模式,而非核心中。udev 的初始化指令碼在系統啟動時建立裝置節點,並且當插入新裝置——加入驅動模組——在sysfs上註冊新的資料後,udev會創新新的裝置節點。

     udev 是一個工作在使用者空間的工具,它能根據系統中硬體裝置的狀態動態更新裝置檔案,包括裝置檔案的建立,刪除,許可權等。這些檔案通常都定義在/dev 目錄下,但也可以在設定檔中指定。udev 必須核心中的sysfs和tmpfs支援,sysfs 為udev 提供裝置入口和uevent 通道,tmpfs 為udev 裝置檔案提供存放空間。

    注意,udev 是通過對核心產生的裝置檔案修改,或增加別名的方式來達到自訂裝置檔案的目的。但是,udev 是使用者模式程式,其不會更改核心行為。也就是說,核心仍然會建立sda,sdb等裝置檔案,而udev可根據裝置的唯一資訊來區分不同的裝置,併產生新的裝置檔案(或連結)。而在使用者的應用中,只要使用新產生的裝置檔案

 

自動建立裝置節點:

在驅動用加入對udev 的支援主要做的就是:在驅動初始化的代碼裡調用class_create(...)為該裝置建立一個class,再為每個裝置調用device_create(...)建立對應的裝置。

    核心中定義的struct class結構體,顧名思義,一個struct class結構體類型變數對應一個類,核心同時提供了class_create(…)函數,可以用它來建立一個類,這個類存放於sysfs下面,一旦建立好了這個類,再調用 device_create(…)函數來在/dev目錄下建立相應的裝置節點。

     這樣,載入模組的時候,使用者空間中的udev會自動響應 device_create()函數,去/sysfs下尋找對應的類從而建立裝置節點。

1、class_create(...) 函數

功能:建立一個類;

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

owner:THIS_MODULE
name  : 名字

 

 

__class_create(owner, name, &__key)原始碼如下:

struct class *__class_create(struct module *owner, const char *name,                   struct lock_class_key *key)  {      struct class *cls;      int retval;        cls = kzalloc(sizeof(*cls), GFP_KERNEL);      if (!cls) {          retval = -ENOMEM;          goto error;      }        cls->name = name;      cls->owner = owner;      cls->class_release = class_create_release;        retval = __class_register(cls, key);      if (retval)          goto error;        return cls;    error:      kfree(cls);      return ERR_PTR(retval);  }  EXPORT_SYMBOL_GPL(__class_create);  

銷毀函數:void class_destroy(struct class *cls)

void class_destroy(struct class *cls)  {      if ((cls == NULL) || (IS_ERR(cls)))          return;        class_unregister(cls);  }  

2、device_create(...) 函數

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

功能:建立一個字元裝置檔案

參數:

      struct class *class  :類
      struct device *parent:NULL
     dev_t devt  :裝置號
     void *drvdata  :null、
     const char *fmt  :名字

返回:

    struct device *

下面是源碼解析:

struct device *device_create(struct class *class, struct device *parent,                   dev_t devt, void *drvdata, const char *fmt, ...)  {      va_list vargs;      struct device *dev;        va_start(vargs, fmt);      dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);      va_end(vargs);      return dev;  }  

下面是一個執行個體:

hello.c

#include <linux/module.h>  #include <linux/fs.h>  #include <linux/cdev.h>  #include <linux/device.h>    static int major = 250;  static int minor=0;  static dev_t devno;  static struct class *cls;  static struct device *test_device;    static int hello_open (struct inode *inode, struct file *filep)  {      printk("hello_open \n");      return 0;  }  static struct file_operations hello_ops=  {      .open = hello_open,  };    static int hello_init(void)  {      int ret;          printk("hello_init \n");          devno = MKDEV(major,minor);      ret = register_chrdev(major,"hello",&hello_ops);        cls = class_create(THIS_MODULE, "myclass");      if(IS_ERR(cls))      {          unregister_chrdev(major,"hello");          return -EBUSY;      }      test_device = device_create(cls,NULL,devno,NULL,"hello");//mknod /dev/hello      if(IS_ERR(test_device))      {          class_destroy(cls);          unregister_chrdev(major,"hello");          return -EBUSY;      }         return 0;  }  static void hello_exit(void)  {      device_destroy(cls,devno);      class_destroy(cls);       unregister_chrdev(major,"hello");      printk("hello_exit \n");  }  MODULE_LICENSE("GPL");  module_init(hello_init);  module_exit(hello_exit);  

 

 test.c

#include <sys/types.h>  #include <sys/stat.h>  #include <fcntl.h>  #include <stdio.h>      main()  {      int fd;          fd = open("/dev/hello",O_RDWR);      if(fd<0)      {          perror("open fail \n");          return ;      }          close(fd);  }  

 

#ubuntu的核心源碼樹,如果要編譯在ubuntu中安裝的模組就開啟這2個KERN_VER = $(shell uname -r)KERN_DIR = /lib/modules/$(KERN_VER)/build            # 開發板的linux核心的源碼樹目錄#KERN_DIR =/lib/modules/2.6.31-14-generic/build#KERN_DIR = /home/book/per/kernel/linux-2.6.22.6#/root/driver/kernelobj-m    += hello.oall:    make -C $(KERN_DIR) M=`pwd` modules #cp:#    cp *.ko /root/porting_x210/rootfs/rootfs/driver_test.PHONY: clean    clean:    make -C $(KERN_DIR) M=`pwd` modules clean    

 

轉自:http://blog.csdn.net/zqixiao_09/article/details/50864014

        http://blog.csdn.net/zqixiao_09/article/details/50849735  

如何自動建立裝置節點

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.