这是内核启动之后要调用的驱动模型的开始代码:

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相关推荐

  1. LINUX驱动模型中bus与platform_bus区别和异同

     LINUX驱动模型中bus与platform_bus区别和异同 首先要明确的是platform_bus是BUS的一个字集,也就是说platform_bus是BUS定义的一个总线类型.可以看到pl ...

  2. Linux驱动模型之注册驱动

    前言 驱动的话我们关心几个点: 驱动是怎么添加到总线管理的设备链表上的? 注册驱动后,它是怎么和设备匹配,并最终调用驱动中的probe()函数的? 数据结构 首先看下数据结构: struct devi ...

  3. linux驱动模型开发——linux platform总线机制讲解与实例开发

    1.概述: 通常在Linux中,把SoC系统中集成的独立外设单元(如:I2C.IIS.RTC.看门狗等)都被当作平台设备来处理. 从Linux2.6起,引入了一套新的驱动管理和注册机制:Platfor ...

  4. 嵌入式驱动解析:从串口驱动到Linux驱动模型

    本文通过对Linux下串口驱动的分析.由最上层的C库.到操作系统系统调用层的封装.再到tty子系统的核心.再到一系列线路规程.再到最底层的硬件操作. 对Linux中的tty子系统进行简要的说明.从理论 ...

  5. Linux 驱动开发 四十三:platform 设备驱动实验(一)

    一.platform 基本概念整理 Linux 系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的软件思路.因此提出驱动.总线和设备的驱动架构,总线负责管理驱动和设备.系统中有很多的物理总线 ...

  6. linux 设备驱动 probe,Linux驱动模型Probe解惑

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 问题 首先来回顾下,Linux设备驱动模型中bus.device和driver三者的关系:bus是物理总线的抽象. de ...

  7. Linux驱动模型核心,第一部分

    翻译自https://www.linuxjournal.com/article/6717 by Greg Kroah-Hartman on June 1, 2003 在Linux2.5内核的开发序列中 ...

  8. 从串口驱动到Linux驱动模型,想转Linux的必会!

    关注.星标公众号,直达精彩内容 ID:技术让梦想更伟大 整理:李肖遥 本文通过对Linux下串口驱动的分析.由最上层的C库.到操作系统系统调用层的封装.再到tty子系统的核心.再到一系列线路规程.再到 ...

  9. 从串口驱动到Linux驱动模型

    大学的时候,帮朋友写的操作系统调研的作业,最近整理过去的文档时候偶然发现,遂作为博客发出来. 从串口驱动到Linux的tty子系统驱动模型简要分析 基于ARM920T核心 Samsung的S3C244 ...

  10. 从零开始之驱动发开、linux驱动(二十三、platform总线之数据驱动分离)

    本节开始引入总线概念. 总线是一种虚拟的概念,不针对任何具体的外设,但是它可以比较好的管理外设. 总线对外设的管理从设备和驱动两个方面说明. 比如我们有3个led灯要控制,一种是向我们之前的那样在软件 ...

最新文章

  1. 详解使用fastboot为Android刷入原厂镜像
  2. 加强Eclipse代码自动提示的方法
  3. 2.自定义变量调节器
  4. lambda 高并发_玩Java 8 – Lambda和并发
  5. 如何批量查问PR值、百度权重、百度快照及收录量,用BlueCatTools批量网站查询工具
  6. 无人驾驶汽车系统入门系列
  7. java实现n选m组合数_求组合数m_n
  8. AD集成DNS区域记录重建及恢复
  9. Playing Atari with Deep Reinforcement Learning 中文 讲解3
  10. logit回归模型的参数估计过程_LOGISTIC模型参数估计及预测实例.pdf
  11. 儒略日 Julian Date
  12. 移动硬盘打不开提示格式化怎么办?
  13. 555定时器与频率测量
  14. eXo Platform 3.0访谈
  15. 对于uniapp的项目,获取设备的一些设备id,首次登陆设备的首台绑定,以及对项目的版本号进行对比进行app升级
  16. 已知字符串STRING以‘$’为结束标志;统计其中小写字母的个数,结果送到COUNT单元,并把该字符串中的小写字母变成大写字母,其它字符保持不变。要求分别在屏幕上输出原字符串以及修改后的字符串。
  17. Centos 安装 glib
  18. 终端类型 xterm linux,Linux的终端类型
  19. django 注册登录邮箱验证功能
  20. kali2021 JDK配置与安装(独一无二的详细)

热门文章

  1. transform2D转换
  2. 递归的应用之字符串反转
  3. idea 报错is already defined as class
  4. linux 后台启动
  5. Oracle 11gR2 GI基本安装手册
  6. [UWP]了解模板化控件(6):使用附加属性
  7. POJ 1088 滑雪 (动规)
  8. [LeetCode] Minimum Window Substring 散列映射问题
  9. rrdtool安装编译提示错误:Can’t locate ExtUtils/MakeMaker.pm in @INC
  10. Directed Minimum Spanning Tree: Chu-Liu/Edmonds Algorithm