Linux設備文件的建立

/************************************************************************************html

*本文爲我的學習記錄,若有錯誤,歡迎指正。node

*本文參考資料: 
linux

*        http://www.cnblogs.com/chen-farsight/p/6154941.html網絡

*        http://www.javashuo.com/article/p-krtbudse-m.html數據結構

************************************************************************************/函數

1. 建立設備文件的兩種方式

(1)手動建立:mknod命令學習

在驅動程序insmod成功以後,經過mknod命令手動建立設備文件至/dev目錄下:mknod /dev/xxx  c  主設備號 次設備號。("c"表示字符設備、"b"表示塊設備、"p"表示網絡設備)spa

(2)自動建立設備文件:mdev.net

在設備驅動註冊到系統後,調用class_create爲該設備在/sys/class目錄下建立一個設備類,再調用device_create函數爲每一個設備建立對應的設備,並經過uevent機制調用mdev(嵌入式linux由busybox提供)來調用mknod建立設備文件至/dev目錄下。指針

2. 自動建立設備文件過程分析

2.1 相關數據結構

struct class和struct device則經過sysfs向用戶層提供信息。

 class_private是class的私有結構,class經過class_private註冊到系統中;device_private是device的私有結構,device經過device_private註冊到系統中。註冊到系統中也是將相應的數據結構加入到系統已經存在的鏈表中,可是這些連接的細節並不但願暴露給用戶,也沒有必要暴露出來,因此纔有private的結構。

//所在文件/kernel/include/linux/device.h
//設備類
struct class 
{
  const char *name; //設備類名稱
  struct module *owner;//建立設備類的module
  struct class_attribute *class_attrs;//設備類屬性
  struct device_attribute *dev_attrs;//設備屬性
  struct kobject *dev_kobj;//kobject再sysfs中表明一個目錄
  .....................
  struct class_private *p;//設備類得以註冊到系統的鏈接件
};

//drivers/base/base.h
struct class_private
{
  struct klist class_devices;//設備類包含的設備(kobject)
  ..................................
  struct class *class;//指向設備類數據結構,即要建立的本級目錄信息
};

 

//所在文件/kernel/include/linux/device.h
struct device 
{
  struct device *parent;        //sysfs/devices/中的父設備
  struct device_private *p;     //設備得以註冊到系統的鏈接件
  struct kobject kobj;          //設備目錄
  const char *init_name;        //設備名稱
  struct bus_type *bus;         //設備所屬總線
  struct device_driver *driver; //設備使用的驅動
  struct klist_node knode_class;//鏈接到設備類的klist
  struct class *class;          //所屬設備類
  .....................
};
//所在文件/kernel/drivers/base/base.h
struct device_private 
{
    struct klist klist_children;    //鏈接子設備
    struct klist_node knode_parent; //加入到父設備鏈表
    struct klist_node knode_driver; //加入到驅動的設備鏈表
    struct klist_node knode_bus;    //加入到總線的鏈表
    struct device *device;          //對應設備結構
};

2.2 建立過程

step1:調用class_create函數在/sys/class目錄下建立一個設備類。

/*
  功能:在/sys/class目錄下建立一個目錄,目錄名是name指定的
  參數:
    struct module *owner - THIS_MODULE
    const char *name - 設備名
  返回值:
    成功:class指針
    失敗: - bool IS_ERR(const void *ptr)  判斷是否出錯
         long PTR_ERR(const void *ptr) 轉換錯誤碼
*/
struct class *class_create(struct module *owner, const char *name);

step2:調用device_create函數在step1建立的設備類目錄下建立具體的設備目錄和設備屬性文件。

/* 
  功能:
    在class指針指向的目錄下再建立一個目錄,目錄名由const char *fmt, ...指出、並導出設備信息(dev_t)
  參數:
    struct class *cls - class指針
    struct device *parent - 父對象,NULL
    dev_t devt - 設備號
    void *drvdata - 驅動私有數據
    const char *fmt, ... - fmt是目錄名字符串格式,...就是不定參數
  返回值:
    成功 - device指針
    失敗 - bool IS_ERR(const void *ptr)  判斷是否出錯
       long PTR_ERR(const void *ptr)   轉換錯誤碼
*/
struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);

step3:在/dev建立設備文件(系統自動進行)

step一、step2都是在sysfs文件系統中建立目錄或者文件,而應用程序訪問的設備文件則須要建立在/dev/目錄下。該項工做由mdev完成(需保證根文件系統支持mdev,由busybox配置)。

2.2 註銷過程

step1:刪除設備類目錄下的設備

/*
  功能:刪除device_create建立的目錄
  參數:
    struct class *cls - class指針
    dev_t devt - 設備號
*/
void device_destroy(struct class *cls, dev_t devt);

step2:刪除/sys/class目錄下的設備類

/*
  功能:刪除class指針指向的目錄
  參數:
    struct class *cls - class指針
*/
void class_destroy(struct class *cls);
相關文章
相關標籤/搜索