linux 驱动机制之设备,驱动,总线

来源:互联网 发布:去黑眼圈眼袋知乎 编辑:程序博客网 时间:2024/05/19 03:26

 

        话说linux driver 机制博大精深,但归根到底主要由:设备(device),驱动(driver),总线(bus)组成,它们三者相互关联,互相寻找,互相映射。

1,device 、driver、bus 之间的关系

        何为设备?linux主要由字符设备,块设备,网络设备等组成。如何驱动这些设备,那就需要相应的driver来控制设备或者硬件。那设备如何去寻找驱动呢?在这里我先给你透露一下,这种牵线搭桥的工作,主要交给了bus。就拿usb 来说吧,一个usb host controller 就对应一条bus;

 

 

上图大致描述三者之间相互依赖的关系,如要理清需从设备查找驱动的流程入下:

首先,当一个设备接入到系统中,系统会将注册相应的设备节点,并告知bus(bus_type);

然后,通过bus_type 中的match函数,来查找driver,并进行匹配的动作。

最后,bus正确查找到设备驱动。进而调用驱动的probe函数,来进行初始化工作。

 

注意!

驱动模块在内核中有两种模式,一种为编译到内核中,另一种为编译成ko。后者需将模块的ko加载到linux kernel 。

 

总之,device,driver,bus 这三架战车,统统有bus 来进行来管理。它主要提供设备匹配驱动,管理设备,管理驱动的功能。

 

2,重要的数据结构

2.1  bus_type

<p>/** * struct bus_type - The bus type of the device * * @name: The name of the bus. * @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id). * @dev_root: Default device to use as the parent. * @bus_attrs: Default attributes of the bus. * @dev_attrs: Default attributes of the devices on the bus. * @drv_attrs: Default attributes of the device drivers on the bus. * @match: Called, perhaps multiple times, whenever a new device or driver *  is added for this bus. It should return a nonzero value if the *  given device can be handled by the given driver. * @uevent: Called when a device is added, removed, or a few other things *  that generate uevents to add the environment variables. * @probe: Called when a new device or driver add to this bus, and callback *  the specific driver's probe to initial the matched device. * @remove: Called when a device removed from this bus. * @shutdown: Called at shut-down time to quiesce the device. * @suspend: Called when a device on this bus wants to go to sleep mode. * @resume: Called to bring a device on this bus out of sleep mode. * @pm:  Power management operations of this bus, callback the specific *  device driver's pm-ops. * @iommu_ops:  IOMMU specific operations for this bus, used to attach IOMMU *              driver implementations to a bus and allow the driver to do *              bus-specific setup * @p:  The private data of the driver core, only the driver core can *  touch this. * * A bus is a channel between the processor and one or more devices. For the * purposes of the device model, all devices are connected via a bus, even if * it is an internal, virtual, "platform" bus. Buses can plug into each other. * A USB controller is usually a PCI device, for example. The device model * represents the actual connections between buses and the devices they control. * A bus is represented by the bus_type structure. It contains the name, the * default attributes, the bus' methods, PM operations, and the driver core's * private data. */struct bus_type { const char  *name;   //设备名称,主要通过名称是否一致,来查找 const char  *dev_name; struct device  *dev_root; struct bus_attribute *bus_attrs; struct device_attribute *dev_attrs; struct driver_attribute *drv_attrs;</p><p> int (*match)(struct device *dev, struct device_driver *drv);   //提供匹配查找的api
 
<span style="color:#009900;">/<span style="color:#000000;">设备 驱动 加载到总线后,会调用到event并发送uevent事件信息到用户空间</span>/ 至于如何发送uevent事件信息,后续再详谈!</span>
 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);</p><p> int (*suspend)(struct device *dev, pm_message_t state); int (*resume)(struct device *dev);</p><p> const struct dev_pm_ops *pm;</p><p> struct iommu_ops *iommu_ops;</p><p> struct subsys_private *p; struct lock_class_key lock_key;};</p>

 

 

2.2 device_driver

 

<p>/** * struct device_driver - The basic device driver structure * @name: Name of the device driver. * @bus: The bus which the device of this driver belongs to. * @owner: The module owner. * @mod_name: Used for built-in modules. * @suppress_bind_attrs: Disables bind/unbind via sysfs. * @of_match_table: The open firmware table. * @acpi_match_table: The ACPI match table. * @probe: Called to query the existence of a specific device, *  whether this driver can work with it, and bind the driver *  to a specific device. * @remove: Called when the device is removed from the system to *  unbind a device from this driver. * @shutdown: Called at shut-down time to quiesce the device. * @suspend: Called to put the device to sleep mode. Usually to a *  low power state. * @resume: Called to bring a device from sleep mode. * @groups: Default attributes that get created by the driver core *  automatically. * @pm:  Power management operations of the device which matched *  this driver. * @p:  Driver core's private data, no one other than the driver *  core can touch this. * * The device driver-model tracks all of the drivers known to the system. * The main reason for this tracking is to enable the driver core to match * up drivers with new devices. Once drivers are known objects within the * system, however, a number of other things become possible. Device drivers * can export information and configuration variables that are independent * of any specific device. */struct device_driver { const char  *name;     //驱动名称 struct bus_type  *bus;  //所关联的总线</p><p> struct module  *owner; const char  *mod_name; /* used for built-in modules */</p><p> bool suppress_bind_attrs; /* disables bind/unbind via sysfs */</p><p> const struct of_device_id *of_match_table; const struct acpi_device_id *acpi_match_table;</p><p> int (*probe) (struct device *dev);   //查找匹配接口,最终会调到驱动的probe函数 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;</p><p> const struct dev_pm_ops *pm;</p><p> struct driver_private *p;};</p>

 

2.3 device

<p>/** * struct device - The basic device structure * @parent: The device's "parent" device, the device to which it is attached. *   In most cases, a parent device is some sort of bus or host *   controller. If parent is NULL, the device, is a top-level device, *   which is not usually what you want. * @p:  Holds the private data of the driver core portions of the device. *   See the comment of the struct device_private for detail. * @kobj: A top-level, abstract class from which other classes are derived. * @init_name: Initial name of the device. * @type: The type of device. *   This identifies the device type and carries type-specific *   information. * @mutex: Mutex to synchronize calls to its driver. * @bus: Type of bus device is on. * @driver: Which driver has allocated this * @platform_data: Platform data specific to the device. *   Example: For devices on custom boards, as typical of embedded *   and SOC based hardware, Linux often uses platform_data to point *   to board-specific structures describing devices and how they *   are wired.  That can include what ports are available, chip *   variants, which GPIO pins act in what additional roles, and so *   on.  This shrinks the "Board Support Packages" (BSPs) and *   minimizes board-specific #ifdefs in drivers. * @power: For device power management. *   See Documentation/power/devices.txt for details. * @pm_domain: Provide callbacks that are executed during system suspend, *   hibernation, system resume and during runtime PM transitions *   along with subsystem-level and driver-level callbacks. * @pins: For device pin management. *  See Documentation/pinctrl.txt for details. * @numa_node: NUMA node this device is close to. * @dma_mask: Dma mask (if dma'ble device). * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all *   hardware supports 64-bit addresses for consistent allocations *   such descriptors. * @dma_parms: A low level driver may set these to teach IOMMU code about *   segment limitations. * @dma_pools: Dma pools (if dma'ble device). * @dma_mem: Internal for coherent mem override. * @archdata: For arch-specific additions. * @of_node: Associated device tree node. * @acpi_node: Associated ACPI device node. * @devt: For creating the sysfs "dev". * @id:  device instance * @devres_lock: Spinlock to protect the resource of the device. * @devres_head: The resources list of the device. * @knode_class: The node used to add the device to the class list. * @class: The class of the device. * @groups: Optional attribute groups. * @release: Callback to free the device after all references have *   gone away. This should be set by the allocator of the *   device (i.e. the bus driver that discovered the device). * * At the lowest level, every device in a Linux system is represented by an * instance of struct device. The device structure contains the information * that the device model core needs to model the system. Most subsystems, * however, track additional information about the devices they host. As a * result, it is rare for devices to be represented by bare device structures; * instead, that structure, like kobject structures, is usually embedded within * a higher-level representation of the device. */struct device { struct device  *parent;</p><p> struct device_private *p;</p><p> struct kobject kobj;    //kobject 结构体 const char  *init_name; /* initial name of the device */ const struct device_type *type;</p><p> struct mutex  mutex; /* mutex to synchronize calls to      * its driver.      */</p><p> struct bus_type *bus;   //<span style="color:#ff0000;">所关联的总线驱动</span> struct device_driver *driver; //<span style="color:#ff0000;">所关联的设备驱动</span> void  *platform_data; /* Platform specific data, device        core doesn't touch it */ struct dev_pm_info power; struct dev_pm_domain *pm_domain;</p><p>#ifdef CONFIG_PINCTRL struct dev_pin_info *pins;#endif</p><p>#ifdef CONFIG_NUMA int  numa_node; /* NUMA node this device is close to */#endif u64  *dma_mask; /* dma mask (if dma'able device) */ u64  coherent_dma_mask;/* Like dma_mask, but for          alloc_coherent mappings as          not all hardware supports          64 bit addresses for consistent          allocations such descriptors. */</p><p> struct device_dma_parameters *dma_parms;</p><p> struct list_head dma_pools; /* dma pools (if dma'ble) */</p><p> struct dma_coherent_mem *dma_mem; /* internal for coherent mem          override */#ifdef CONFIG_DMA_CMA struct cma *cma_area;  /* contiguous memory area for dma        allocations */#endif /* arch specific additions */ struct dev_archdata archdata;</p><p> struct device_node *of_node; /* associated device tree node */ struct acpi_dev_node acpi_node; /* associated ACPI device node */</p><p> dev_t   devt; /* dev_t, creates the sysfs "dev" */ u32   id; /* device instance */</p><p> spinlock_t  devres_lock; struct list_head devres_head;</p><p> struct klist_node knode_class; struct class  *class; const struct attribute_group **groups; /* optional groups */</p><p> void (*release)(struct device *dev); struct iommu_group *iommu_group;};</p>


 



 

上述为本人对linux 三架战车的理解,如有不足或者有误的地方,还望大家指出,并相互学习。

 

 

 

0 0