标签:const 内存 devices 私有 init 意义 分配 源码 uil
Linux 系统下的驱动最后都是以如下这个结构体呈现在系统中的,注意其中的dev_pm_ops增加来准备替换platform_driver中的电源管理相关的内容的。这里内容主要都是流程梳理的没有详细罗列具体的Linux内核代码的内容所以可以参考源码来学习。也可以看文末的参考博客写的比较傲详细。
struct device_driver { const char *name; struct bus_type *bus; /*Linux 下驱动都是应该挂在总线地下的*/ struct module *owner; const char *mod_name; /* used for built-in modules */ bool suppress_bind_attrs; /* 如果他为1 则取消暴露到文件系统中的绑定相关操作接口 */ const struct of_device_id *of_match_table; /* 设备树兼容属性表 */ const struct acpi_device_id *acpi_match_table;/* ACPI兼容属性表 */ 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; /* 驱动私有数据 */ };
系统给驱动开发提供了一些接口,其中driver_register和driver_unregister两个接口常使用以完成驱动的注册和卸载。
这里没有很结合源码进行分析,可以自行参考源码进行分析,3.x的内核和4.0的内核区别会有一些但是不是很大。依然有参考意义
1、driver_register 1、不知道为什么需要检查驱动如果有probe函数总线也有就需要出一个警告,要求使用总线提供的方法,(也就是说driver里的方法要废弃??) 2、检查目标总线上是否已经有同名驱动(因为避免设备和驱动多对多) 3、bus_add_drv 1、bus_get() 其实kobject.refcnt++ 2、申请分配驱动私有管理数据结构内存priv并绑定到驱动的私有数据指针上,并初始化主要是klist_devices和priv->kobj相关的。 3、kobject_init_and_add 主要是kobject相关调用 4、klist_add_tail 将驱动添加到bus的klist中去 5、driver_attach(drv);/*驱动和设备的匹配 新内核新增的新异步匹配机制这里和老内核有区别 */ 1、bus_for_each_dev(bus,device_start,data,fn(struct device*,void))这个函数设备注册的时候也会调用其中的fn传入的是__driver_attach 2、遍历bus上的klist_devices 依次__driver_attach(dev,drv)进行匹配 1、__driver_attach 1、如果驱动总线的mach函数存在调用驱动总线的mach函数mach(dev,drv)返回0就算匹配上就会返回了 2、前一步未匹配上调用driver_probe_device(drv,dev)做了一堆检查后实际调用really_probe(dev,drv),正如函数名一样他会真正执行总线的probe函数 1、这里有个机制,内核会优先执行对应总线的probe函数,如果它不存在则会查看对应驱动的probe函数是否存在,存在就调用这是真正的probe操作,在这之前 这个函数还将sysfs下建立好了对应的文件,如果失败后面会删除并返回,同时将dev的driver句柄置空NULL,这次的驱动和设备匹配失败。 2、上一步成功后将进行驱动和设备的绑定driver_bound 6、上一步如果失败就推出驱动注册,成功了继续。 7、module_add_driver 8、前面成功匹配以将在sysfs下建立了驱动的文件夹和文件,后的操作就是继续创建一些驱动文件接口和属性文件在驱动目录下。 9、至此驱动注册完成,在这之中驱动的探测和绑定均以执行完毕。
驱动的卸载 1、driver_unregister 1、driver_remove_groups 删除对应目录下的文件 2、bus_remove_driver 1、删除文件 2、klist的维护 3、driver_detach 这个是关建,就是将之前匹配的驱动和设备解绑。 循环 1、 list_entry(drv->p->klist_devices.k_list.prev,。。。 找到驱动上的设备 2、 __device_release_driver 1、删除sysfs下的文件 因为驱动下会有文件指向设备,设备下也有文件直线驱动所以这里会删两次,一次是驱动目录下的第二次是设备下的。 2、设备驱动句柄置空,此时设备还是在的只是没有对应驱动。
参考:https://blog.csdn.net/qq_16777851/article/details/81459931
标签:const 内存 devices 私有 init 意义 分配 源码 uil
原文地址:https://www.cnblogs.com/w-smile/p/13289754.html