Linux那些事儿之我是Sysfs(3)设备模型上层容器

来源:互联网 发布:怎样不让数据自动连接 编辑:程序博客网 时间:2024/05/17 02:09

§1 bus
系统中总线由struct bus_type描述,定义为:

include/linux/device.h

struct bus_type {const char*name;总线类型的名称const char*dev_name;struct device*dev_root;struct device_attribute*dev_attrs;/* use dev_groups instead */const struct attribute_group **bus_groups;const struct attribute_group **dev_groups;const struct attribute_group **drv_groups;int (*match)(struct device *dev, struct device_driver *drv);int (*uevent)(struct device *dev, struct kobj_uevent_env *env);int (*probe)(struct device *dev);int (*remove)(struct device *dev);void (*shutdown)(struct device *dev);int (*online)(struct device *dev);int (*offline)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct dev_pm_ops *pm;const struct iommu_ops *iommu_ops;struct subsys_private *p;struct lock_class_key lock_key;};



每个bus_type对象都对应/sys/bus目录下的一个子目录,如PCI总线类型对应于/sys/bus/pci。在每个这样的目录下都存在两个子目录:devices和drivers(dev_groups和drv_groups)。其中devices子目录描述连接在该总线上的所有设备,而drivers目录则描述与该总线关联的所有驱动程序。与device_driver对象类似,bus_type结构还包含几个函数(match()、hotplug()等)处理相应的热插拔、即插即拔和电源管理事件。


§2 device
系统中的任一设备在设备模型中都由一个device对象描述,其对应的数据结构struct device
定义为:

include/linux/device.h

struct device {struct device*parent;struct device_private*p;struct kobject kobj;const char*init_name; /* initial name of the device */const struct device_type *type;struct mutexmutex;/* mutex to synchronize calls to * its driver. */struct bus_type*bus;/* type of bus device is on */struct device_driver *driver;/* which driver has allocated this   device */void*platform_data;/* Platform specific data, device   core doesn't touch it */void*driver_data;/* Driver data, set and get with   dev_set/get_drvdata */struct dev_pm_infopower;struct dev_pm_domain*pm_domain;#ifdef CONFIG_PINCTRLstruct dev_pin_info*pins;#endif#ifdef CONFIG_NUMAintnuma_node;/* NUMA node this device is close to */#endifu64*dma_mask;/* dma mask (if dma'able device) */u64coherent_dma_mask;/* Like dma_mask, but for     alloc_coherent mappings as     not all hardware supports     64 bit addresses for consistent     allocations such descriptors. */unsigned longdma_pfn_offset;struct device_dma_parameters *dma_parms;struct list_headdma_pools;/* dma pools (if dma'ble) */struct dma_coherent_mem*dma_mem; /* internal for coherent mem     override */#ifdef CONFIG_DMA_CMAstruct cma *cma_area;/* contiguous memory area for dma   allocations */#endif/* arch specific additions */struct dev_archdataarchdata;struct device_node*of_node; /* associated device tree node */struct acpi_dev_nodeacpi_node; /* associated ACPI device node */dev_tdevt;/* dev_t, creates the sysfs "dev" */u32id;/* device instance */spinlock_tdevres_lock;struct list_headdevres_head;struct klist_nodeknode_class;struct class*class;const struct attribute_group **groups;/* optional groups */void(*release)(struct device *dev);struct iommu_group*iommu_group;booloffline_disabled:1;booloffline:1;};


parent域指向父对象。Device对象还内嵌一个kobject对象,用于引用计数管理并通过它实现设备层次结构。Driver域指向管理该设备的驱动程序对象,而driver data则是提供给驱动程序的数据。Bus域描述设备所连接的总线类型。


内核提供了相应的函数用于操作device对象。其中device_register()函数将一个新的device对象插入设备模型,并自动在/sys/devices下创建一个对应的目录。device_unregister()完成相反的操作,注销设备对象。get_device()和put_device()分别增加与减少设备对象的引用计数。通常device结构不单独使用,而是包含在更大的结构中作为一个子结构使用,比如描述PCI设备的struct pci_dev,还有我们ldd_dev,其中的dev域就是一个device对象。


§3. driver
系统中的每个驱动程序由一个device_driver对象描述,对应的数据结构定义为:

include/linux/device.h

struct device_driver {const char*name;设备驱动程序的名称struct bus_type*bus;该驱动所管理的设备挂接的总线类型struct module*owner;const char*mod_name;/* used for built-in modules */bool suppress_bind_attrs;/* disables bind/unbind via sysfs */const struct of_device_id*of_match_table;const struct acpi_device_id*acpi_match_table;int (*probe) (struct device *dev);int (*remove) (struct device *dev);void (*shutdown) (struct device *dev);int (*suspend) (struct device *dev, pm_message_t state);int (*resume) (struct device *dev);const struct attribute_group **groups;const struct dev_pm_ops *pm;struct driver_private *p;};



内核提供类似的函数用于操作device_driver对象,如get_driver()增加引用计数,driver_register()用于向设备模型插入新的driver对象,同时在sysfs文件系统中创建对应的目录。device_driver()结构还包括几个函数,用于处理热拔插、即插即用和电源管理事件。

可能你面对刚刚列举出来的一些列数据结构,感到很苦恼,很莫名其妙。没关系,我接下来讲个例子您就明白了。

0 0
原创粉丝点击