Linux驱动模型解析bus之platform bus
这是内核启动之后要调用的驱动模型的开始代码:
drivers/base/init.c/*** driver_init - initialize driver model.** Call the driver model init functions to initialize their* subsystems. Called early from init/main.c.*/ void __init driver_init(void) {/*These are the core pieces*/devices_init(); // /sys/devicesbuses_init(); // /sys/busclasses_init(); // /sys/classfirmware_init();hypervisor_init();/*These are also core pieces, but must come after the* core core pieces.*/platform_bus_init();system_bus_init();cpu_dev_init();memory_dev_init(); }
且看platform_bus_init
drivers/base/platform.c
struct device platform_bus ={.bus_id= "platform", };
struct bus_type platform_bus_type ={.name= "platform",.dev_attrs=platform_dev_attrs,.match=platform_match,.uevent=platform_uevent,.pm=PLATFORM_PM_OPS_PTR, };
int __init platform_bus_init(void) {interror;
/* /sys/devices/platform (this platform is bus_id's value) */
error= device_register(&platform_bus); if(error) returnerror;
/* /sys/bus/platform (this platform is the value of bus_type's name field) */
error= bus_register(&platform_bus_type); if(error) device_unregister(&platform_bus); returnerror; }
这里讲述 bus_register(&platform_bus_type):
/*** struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure.** @subsys - the struct kset that defines this bus. This is the main kobject* @drivers_kset - the list of drivers associated with this bus* @devices_kset - the list of devices associated with this bus* @klist_devices - the klist to iterate over the @devices_kset* @klist_drivers - the klist to iterate over the @drivers_kset* @bus_notifier - the bus notifier list for anything that cares about things* on this bus.* @bus - pointer back to the struct bus_type that this structure is associated* with.** This structure is the one that is the actual kobject allowing struct* bus_type to be statically allocated safely. Nothing outside of the driver* core should ever touch these fields.*/ structbus_type_private {struct kset subsys;struct kset *drivers_kset;struct kset *devices_kset;structklist klist_devices;structklist klist_drivers;structblocking_notifier_head bus_notifier;unsignedint drivers_autoprobe:1;struct bus_type *bus; };
int bus_register(struct bus_type *bus) {intretval;struct bus_type_private *priv; priv= kzalloc(sizeof(structbus_type_private), GFP_KERNEL);if (!priv)return -ENOMEM; priv->bus =bus; bus->p =priv; BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier); retval= kobject_set_name(&priv->subsys.kobj, "%s", bus->name);if(retval)goto out; priv->subsys.kobj.kset =bus_kset; priv->subsys.kobj.ktype = &bus_ktype; priv->drivers_autoprobe = 1; retval= kset_register(&priv->subsys);if(retval)goto out; retval= bus_create_file(bus, &bus_attr_uevent);if(retval)gotobus_uevent_fail; priv->devices_kset = kset_create_and_add("devices", NULL,&priv->subsys.kobj);if (!priv->devices_kset) { retval= -ENOMEM;gotobus_devices_fail; } priv->drivers_kset = kset_create_and_add("drivers", NULL,&priv->subsys.kobj);if (!priv->drivers_kset) { retval= -ENOMEM;gotobus_drivers_fail; } klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); klist_init(&priv->klist_drivers, NULL, NULL); retval=add_probe_files(bus);if(retval)gotobus_probe_files_fail; retval=bus_add_attrs(bus);if(retval)gotobus_attrs_fail; pr_debug("bus: '%s': registered\n", bus->name);return 0;
struct bus_type_private *priv指向struct bus_type,这里会显示/sys/bus/platform
retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
priv->subsys.kobj.kset = bus_kset;
retval = kset_register(&priv->subsys);// subsys is a kset.
这里显示/sys/bus/platform/devices
priv->devices_kset = kset_create_and_add("devices", NULL, &priv->subsys.kobj);
这里显示/sys/bus/platform/drivers
priv->drivers_kset = kset_create_and_add("drivers", NULL, &priv->subsys.kobj);
kset_create_and_add--->kset_register
/** * kset_register - initialize and add a kset. * @k: kset.*/ int kset_register(struct kset *k) {interr;if (!k)return -EINVAL; kset_init(k); // INIT_LIST_HEAD(&k->kobj->entry); INIT_LIST_HEAD(&k->list); err= kobject_add_internal(&k->kobj);if(err)returnerr; kobject_uevent(&k->kobj, KOBJ_ADD);return 0; }
static int kobject_add_internal(struct kobject *kobj) { kobj_kset_join(kobj);error=create_dir(kobj); // /sys/bus/platform }
/*add the kobject to its kset's list*/ static void kobj_kset_join(struct kobject *kobj) {if (!kobj->kset)return; kset_get(kobj->kset); spin_lock(&kobj->kset->list_lock); list_add_tail(&kobj->entry, &kobj->kset->list); spin_unlock(&kobj->kset->list_lock); }
If a kset is associated with a kobject, then the parent for the kobject can be set to
NULL in the call to kobject_add() and then the kobject's parent will be the kset itself.
确切的说是kobject's parent赋值为kobject关联的kset's kobjcect
structkobject {const char *name;struct list_head entry;struct kobject *parent;struct kset *kset;struct kobj_type *ktype;struct sysfs_dirent *sd;structkref kref; unsignedint state_initialized:1; unsignedint state_in_sysfs:1; unsignedint state_add_uevent_sent:1; unsignedint state_remove_uevent_sent:1; };
* *A kset defines a group of kobjects. They can be individually* different "types"but overall these kobjects all want to be grouped* together and operated on inthe same manner. ksets are used to*define the attribute callbacks and other common events that happen to*a kobject.* * @list: the list of all kobjects for thiskset* @list_lock: a lock foriterating over the kobjects* @kobj: the embedded kobject for this kset (recursion, isn't it fun...)* @uevent_ops: the set of uevent operations for thiskset. These are*called whenever a kobject has something happen to it so that the kset* can add new environment variables, or filter out the uevents ifso*desired.*/ structkset {structlist_head list; spinlock_t list_lock;structkobject kobj;struct kset_uevent_ops *uevent_ops; };
structlist_head {struct list_head *next, *prev; };
从list_add_tail(&kobj->entry, &kobj->kset->list); 调用中,我们一下子就明白了,
bus =&struct bus_type platform_bus_type;bus->p->->subsys.kobj.kset = bus_kset;//bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); 创建了bus的kset显示/sys/bus所以&kobj->kset->list就是bus_kset->list,list_add_tail就是把bus->p->->subsys.kobj.entry加入到bus_kset->list链表中。bus_kset包含不同bus的subsys的kset,而代表subsys的kset的就是这个kset中的kobject。所以把kobjetct的entry加入到表示kset的kset->list中。换句话说,struct kset这个集合包含的内容由其嵌入的struct list_head list来表示,这个struct kset自身由其嵌入的struct kobject kobj来表示。所以这里就是把platform这个kset加入到bus这个kset中。用户空间的视图表示就是/sys/bus/platform。
转载于:https://www.cnblogs.com/georgejguo/p/driver_model-platformbus.html
Linux驱动模型解析bus之platform bus相关推荐
- LINUX驱动模型中bus与platform_bus区别和异同
LINUX驱动模型中bus与platform_bus区别和异同 首先要明确的是platform_bus是BUS的一个字集,也就是说platform_bus是BUS定义的一个总线类型.可以看到pl ...
- Linux驱动模型之注册驱动
前言 驱动的话我们关心几个点: 驱动是怎么添加到总线管理的设备链表上的? 注册驱动后,它是怎么和设备匹配,并最终调用驱动中的probe()函数的? 数据结构 首先看下数据结构: struct devi ...
- linux驱动模型开发——linux platform总线机制讲解与实例开发
1.概述: 通常在Linux中,把SoC系统中集成的独立外设单元(如:I2C.IIS.RTC.看门狗等)都被当作平台设备来处理. 从Linux2.6起,引入了一套新的驱动管理和注册机制:Platfor ...
- 嵌入式驱动解析:从串口驱动到Linux驱动模型
本文通过对Linux下串口驱动的分析.由最上层的C库.到操作系统系统调用层的封装.再到tty子系统的核心.再到一系列线路规程.再到最底层的硬件操作. 对Linux中的tty子系统进行简要的说明.从理论 ...
- Linux 驱动开发 四十三:platform 设备驱动实验(一)
一.platform 基本概念整理 Linux 系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的软件思路.因此提出驱动.总线和设备的驱动架构,总线负责管理驱动和设备.系统中有很多的物理总线 ...
- linux 设备驱动 probe,Linux驱动模型Probe解惑
8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 问题 首先来回顾下,Linux设备驱动模型中bus.device和driver三者的关系:bus是物理总线的抽象. de ...
- Linux驱动模型核心,第一部分
翻译自https://www.linuxjournal.com/article/6717 by Greg Kroah-Hartman on June 1, 2003 在Linux2.5内核的开发序列中 ...
- 从串口驱动到Linux驱动模型,想转Linux的必会!
关注.星标公众号,直达精彩内容 ID:技术让梦想更伟大 整理:李肖遥 本文通过对Linux下串口驱动的分析.由最上层的C库.到操作系统系统调用层的封装.再到tty子系统的核心.再到一系列线路规程.再到 ...
- 从串口驱动到Linux驱动模型
大学的时候,帮朋友写的操作系统调研的作业,最近整理过去的文档时候偶然发现,遂作为博客发出来. 从串口驱动到Linux的tty子系统驱动模型简要分析 基于ARM920T核心 Samsung的S3C244 ...
- 从零开始之驱动发开、linux驱动(二十三、platform总线之数据驱动分离)
本节开始引入总线概念. 总线是一种虚拟的概念,不针对任何具体的外设,但是它可以比较好的管理外设. 总线对外设的管理从设备和驱动两个方面说明. 比如我们有3个led灯要控制,一种是向我们之前的那样在软件 ...
最新文章
- 详解使用fastboot为Android刷入原厂镜像
- 加强Eclipse代码自动提示的方法
- 2.自定义变量调节器
- lambda 高并发_玩Java 8 – Lambda和并发
- 如何批量查问PR值、百度权重、百度快照及收录量,用BlueCatTools批量网站查询工具
- 无人驾驶汽车系统入门系列
- java实现n选m组合数_求组合数m_n
- AD集成DNS区域记录重建及恢复
- Playing Atari with Deep Reinforcement Learning 中文 讲解3
- logit回归模型的参数估计过程_LOGISTIC模型参数估计及预测实例.pdf
- 儒略日 Julian Date
- 移动硬盘打不开提示格式化怎么办?
- 555定时器与频率测量
- eXo Platform 3.0访谈
- 对于uniapp的项目,获取设备的一些设备id,首次登陆设备的首台绑定,以及对项目的版本号进行对比进行app升级
- 已知字符串STRING以‘$’为结束标志;统计其中小写字母的个数,结果送到COUNT单元,并把该字符串中的小写字母变成大写字母,其它字符保持不变。要求分别在屏幕上输出原字符串以及修改后的字符串。
- Centos 安装 glib
- 终端类型 xterm linux,Linux的终端类型
- django 注册登录邮箱验证功能
- kali2021 JDK配置与安装(独一无二的详细)
热门文章
- transform2D转换
- 递归的应用之字符串反转
- idea 报错is already defined as class
- linux 后台启动
- Oracle 11gR2 GI基本安装手册
- [UWP]了解模板化控件(6):使用附加属性
- POJ 1088 滑雪 (动规)
- [LeetCode] Minimum Window Substring 散列映射问题
- rrdtool安装编译提示错误:Can’t locate ExtUtils/MakeMaker.pm in @INC
- Directed Minimum Spanning Tree: Chu-Liu/Edmonds Algorithm