linux内核 compoent框架分析和使用(基于zynq mpsoc)

本文基于kernel 5.10版本,在进行DRM显示框架的分析过程中,需要对component框架比较了解,顺便学习了。

一、背景

linux内核中的驱动,需要有一定的加载顺序,用来解决驱动之间的依赖问题。虽然说linux内核有定传统的驱动优先级,用来定义驱动的先后顺序,但是不足以更加细分的加载。

有的驱动可以独立加载而不依赖于其他驱动,但是在一个比较庞大的驱动面前,细分驱动的加载就比较重要了,因为这些庞大的驱动,环环相扣,一环出了问题就影响整个驱动的顺利走完。因此component架构一般用于DRM显示驱动架构和ALSA音频驱动架构。

个人认为component并不是和DRM和ALSA绑定的,更多的是一种内核基础设施,自己编写的驱动如有依赖关系,完全可以使用上component这个工具。

二、component介绍

component架构主要的逻辑编写在内核源码的driver/base/component.c

最后系统应该呈现出来的是这样的组织:


上面呈现了3种对象:component、master、component_match

可以看到无论是master还是component都有他们的操作集ops。

在component架构中,master在一个复杂驱动(drm或者alsa)中被看成在一个统筹的角色,各个component表示在这个复杂驱动中不可或缺的组件。开始各个component各自注册进系统,并且尝试唤醒master来统筹(因为component都不知道自己是不是最后一个注册的,所以都有责任去尝试唤醒master),最后master将自己注册进系统,然后根据master自己定义的对比方法找到匹配的component,调用他们的回调,通常这些回调包含了component自己的关键步骤。

下面将一步一步分解上面的过程。

三、component注册

如开头所说,驱动都是以probe进入加载的,但是probe们并没有特别明确的加载顺序,因此进入probe的时候,可以使用component架构,将自己抽象成component注册进系统,然后等待master来统筹每个conponent的加载顺序,现在就来看看component如何加载。

  • 使用component_add()注册进系统
  • 使用component_del()从系统中注销

所谓的注册和注销,无非就是内核的组织形式。在这里。component是以链表形式去组织的,在系统启动后就已经静态注册了两个链表头,用来组织master和component。

/*driver/base/component.c*/

static LIST_HEAD(component_list);
static LIST_HEAD(masters);

关键是上面的3步

①内存上申请component对象

②初始化component,主要是component绑定一个操作集合,里面有bind和unbind回调,一般在bind里面包含了关于这个component需要被安排做的事情,这个五星级重要。

③将component加入component_list链表,形成组织

其实还有最后一步,那就是尝试去唤醒master来回调各个componnet的bind。其实componnet的注册还是挺简单的,简单一句话就是自己管自己,将自己注册好,至于什么时候bind回调能执行,并不清楚。经过componnet_add那么componnet链表中就出出现了第一个对象了,且这个对象包含一个操作集合,包含了bind回调。

最后,还发现了注册componnet的时候还需要传入一个device对象,证明了component是属于某个对象的,那样通过componnet完全可以找到被抽象的设备。

使用例子:

二、component_match的构建

component_match是一个用于匹配的对象,用于匹配master和componnet,因为系统中有很多componnet,一个master并不是统筹全系统的componnet,而是统筹有一定特征的coponent,所以需要一个匹配的工具,那就是component_match。

如总框架图:

一个master对应一个component_match,一个component_match对应一组component_match_array.

  • 使用component_match_add来构建一个component_match和一组component_match_array
static inline void component_match_add(struct device *master,
	struct component_match **matchptr,
	int (*compare)(struct device *, void *), void *compare_data)

①如果传进来的component_match对象是NULL,那么意味着需要创建一个新的

②如果一组component_match_array已经满了,或者是空的,那么就新增16个空位

③填充一个component_match_array,里面包含了很重要的compare函数和compare 数据

component_match_array到底是什么,可以说一项component_match_array对应一个component,因此看到了通过component_match_array可以找到component。

就这样,通过component_match_add就可以往component_match里面增加一个个的component_match_array。至于有什么用,在后面再来分析。

使用例子:

第一个参数仅仅只是devm自动管理架构使用的,其余三个参数才是我们最需要关注的。分别是component_match、compare对比函数,compare数据。在这里可以看到,如果要对比的话,此处采用的方法是比较设备的设备树节点。

三、master的注册

master作为一个统筹的角色,在所有component都被注册进系统后,就可以将master注册进系统,

  • 通过component_master_add_with_match()将master注册进系统
int component_master_add_with_match(struct device *dev,
	const struct component_master_ops *ops,
	struct component_match *match)

可以看到传入的参数是master依附的设备,master的操作集合,以及刚刚构建好的component_match函数,这正好对应上了:一个master对应一个component_match。

接下来看看master是如何注册的:

①将master加进系统之前重新规划component_match指向的数组,修改成真实存在的数量,因为要知道我们一下子申请了16个空位,但是加进去的不一定有16个component。

②内存申请master对象,并且绑定依附的设备,绑定master操作集,绑定match

③debugfs系统增加内容

④将master加进master链表,也就是总图的第二个链表

⑤尝试唤醒master

可以看到无论是component还是master都会尝试唤醒master。

使用例子:

一定是component_match填充完之后才进行master的注册

四、如何唤醒master?

这个是整个component架构的重头戏,正是这个流程使得各个bind回调能按顺序执行。

1、当component注册时候尝试唤醒master

当某个component注册时候尝试去唤醒master的时候,会遍历master链表。find_coponents()对每个master下面维护的component_match指向的component_match_array数组遍历,因为component和component_match_array一一对应,如果发现component_match_array已经绑定了component,那么就跳过,如果发现一个孤立的component_match_array,就会调用find_component()遍历component链表,如果发现已经绑定了master了就跳过,如果发现一个孤立的coponent,就调用孤立的component_match_array里面保存的compare对比函数来查看这个component是否符合要求(这个根据compare函数的逻辑),如果符合要求,就找到了一个component,将component和master关联,将component和component_match_array关联。

找到一个master所有的component后会调用master的bind函数。最后在master的bind函数里面调用component_bind_all()完成对各个component的bind顺序执行。

其实整个系统可能就只有两个master,DRM和ALSA的,只是为了方便理解,未经过考证。

2.当master注册时候如何唤醒master?

当master注册时候,并不需要遍历master链表,因为当master注册的时候,他知道自己是master,不需要关注其他master,只需要关注自己维护有哪些componnet,因此会遍历component链表。知道到有符合条件的component最后也是调用master的bind函数。

五、master的bind函数如何按顺序执行各个component的bind函数?

通常在master的bind函数里面调用一个接口component_bind_all()

int component_bind_all(struct device *master_dev, void *data)

首先通过设备找到对应的master,因为所有的对象都有关联了。再按照master→component_match_array→componnet的顺序找到componnet,然后就能调用component的bind函数

六、关于设备树的ports节点如何书写

上面说到component_match_add即构建一项又一项的component_match_array,除了用component_match_add()写死构建外,还可以使用设备树的ports节点来灵活更改。所以一般再抽象成master的驱动里面会又一段解析这种设备树节点的代码。此处以xilinx DRM的master来举例子:

首先从master的设备数节点里面寻找“ports”属性,使用of_parse_phandle寻找指定的设备数节点(标号pl_disp_port),这个节点完全可以写在其他地方,然后通过parent找到了父节点(名字drm-pl-disp),然后将这个父节点加入component_match_array。最后根据ports下port指定的remote-endpoints 找到了另一端的remote-endpoint,加入component_match_array就好比两个接头。

七、总结

component_match_add 对应component_match_array的构建

component__add 对应component的链表构建

component_master_add_with_match对应master的链表构建即master bind的执行

component_bind_all()是master最后执行各个bind的接口
查看系统已有组件:cat /sys/kernel/debug/device_component/XX

weixin_44551105
关注 关注
  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
linux kernel --component组件用法
weixin_42097108的博客
12-10 437
kernel - component组件用法 linux component组件架构分析
【SemiDrive源码分析】【Display模块】36 - Android侧 DRM代码分析
|~~~热爱生活、努力学习的小伙汁~~~|
07-10 994
【SemiDrive源码分析】【Display模块】36 - Android侧 Display显示流程分析
linux component组件架构分析
buls的博客
09-19 3111
component 组件系统架构分析 背景介绍 任何架构的提出都是有其现实应用背景的,都是为了解决一些现实问题。而component系统架构的提出就是出于这样一种现实需求:构建功能系统! 系统就是各种功能单元(组件)的有序结合。一个系统,只有集齐了它的所有组件才能正常工作。 可以打个比方:一辆车就是一个系统,它由各种组件–发动机,变速箱,中控台,车轮等构成。 一辆车,只装上发动机,或变速箱。是不能工作的,必须安装了所有的组件,才能开始发动。 而发动的过程,也是有顺序要求的,如先采离合,再挂当(变速箱初始化)
Linux驱动component
ZHUYJUN的博客
05-17 1027
0 前言 component算是Linux内核中用的比较多的一类结构,这篇文章具体分析一波。 1component_match_add void component_match_add(struct device *dev, struct component_match **matchptr, int (*compare)(struct device *, void *), void *compare_data) { struct component_match *match...
Linux component框架
hongyeying的专栏
12-08 2719
component是什么样子的
Linux component -- avahi
12-01 942
Main Page:  http://avahi.org/wiki: http://en.wikipedia.org/wiki/Avahi_%28software%29  Avahi is an Implementation of the DNS Service Discovery and Multicast DNS specifications for
linux component文件,Linux DRM那些事-component框架介绍
weixin_32175667的博客
04-30 723
一、component介绍Linux内核component代码实现文件:drivers/base/component.c。使用git log -p component.c命令,可以查看该文件的第一次提交记录。commit 2a41e6070dd7ef539d0f3b1652b4839d04378e11Author: Russell King Date: Fri Jan 10 23:23:37 ...
bean注解和compoent注解的区别
07-22
在 Spring 框架中,`@Bean` 注解和@Component` 注解是两个常的注解,它有一些区别和不同的使用场景。 1. `@Bean` 注解: - `@Bean` 注解通常用于在配置类(Configuration Class)中声明一个 Bean。配置类是一个被 ...
Android声明式UI框架 Litho 初探——基础使用
鸿蒙开发知识记录
09-09 1520
初衷 Litho作为一个高性能的UI引擎,学习曲线还是比较高的,但是在国内能用的资料非常少(大部分都是相互复制的”Hello Word“教程),国外除了Litho自己的文档外,也没有太多教程。这几篇教程也是我边学边写。如果有那里理解不到位的地方,欢迎指正。 Litho 是什么 Litho是一个用于在Android上构建高效用户界面(UI)的声明性框架。但不同以往的UI框架,它的底层是Yoga,它通过将不需要交互的UI转换为Drawable来渲染视图,通过Yoga来完成组件布局的异步或同步(可根据场景定
基于 ELK 的 mongo 日志分析简单实践
Odew
05-09 2925
基于Elk 的日志分析简单实践 基于Elk 的日志分析简单实践 前言 Elk 简介 部署 logstash 1. 数据源输入 2. 日志分析和过滤 3. 输出至 elastcisearch。 Kibana 1. Setting 2. Discover 3. Visualize 应用场景发散 问题总结与优化 参考资料 前言 ​ Elk 是 Elasti...
qml compoent详解
04-24
QML 组件是 QML 语言的最基本元素之一,可以将一些可重复使用的功能代码封装起来,方便在不同的 QML 页面或项目中进行复用。组件可以包含属性、信号和函数,它们共同构成了一个可自包含的 QML 实体。 在 QML 中,...
Linux Component概述和高通component使用
lz_1990的专栏
12-07 450
为了让subsystem按照一定顺序初始化设备才提出来的。subsystem中由很多设备模块,内核加载这些模块的时间不确定。子系统内有些模块是需要依赖其它模块先初始化才能进行自己初始化工作(例如v4l2 subdev和v4l2 video device),这时就要用到component框架。例如v4l2 subdev和v4l2 video device中,谁依赖谁先创建?
linux kernel component框架分析
shikivs的博客
12-18 5611
基于4.1.15内核 kernel中的component是为了subsystem能够按照一定的顺序初始化设备而提出的架构。 subsystem中由较多设备模块组成,而内核加载每个模块时间不定。则需要component来保证需最后初始化的设备加载前,所需设备全部加载完毕。 1 component框架描述 1.1 架构描述 在内核的一个subsystem中, component包含两个基本概念,mas...
kernel - component
weixin_30390075的博客
01-04 299
component在多个模块相互关联并且存在一定的初始化顺序时非常有用。现分析下其工作原理,以便后续组织自己的驱动模块。 一、component_match分析 component_match在master和component匹配时用,它包含一个匹配函数指针和一个void *类型的数据指针,其结构体定义如下: struct component_match { size_t allo...
Linux ALSA声卡驱动之三:component、dai、codec以及platform之间的关系
热门推荐
moonlinux20704的博客
03-12 1万+
一、背景概述 上节说到platform_device加载,触发mt76xx_i2s_driver、soc_driver、mt76xx_pcm_driver驱动程序的probe,这里面做了哪些工作,如下图 二、snd_soc_component与snd_soc_dai的关系 1、mt76xx_i2s_drv_probe的实现 在...
LCD DRM component 框架分析
qq_33782617的博客
08-08 1569
基于rk平台,以 DRM LCD 驱动为对象,对linux kernel下的component 框架进行分析
Display DRM架构之component
fengchaochao123的博客
08-29 2989
刚开始做显示驱动的时候就一直接触到component组件,DRM中的各个模块使用component来管理。最近学习了一下这一块源码,彻底明白了component的机制。 为什么引入component机制 为什么会引入这个这个机制呢? display和camera等这种框架会涉及到很多模块,像高通处理中,里面有MDP,mipi,hdmi,edp等等其他模块;模块之间会存在依赖,就需要考虑加载顺序。虽然内核也提供了像core_initcall,arch_initcall,late_initcall这些接口
component框架
weixin_46027271的博客
01-02 1182
Linux驱动component框架使用
Linux设备驱动probe过程(四)
最新发布
zxcv788999的博客
05-09 1007
Component框架是为了设备驱动能够按照一定顺序初始化而提出的架构。Linux中复杂的子系统一般由多个设备模块组成,而内核加载每个模块时间和顺序不定,通过component框架可以保证设备初始化加载前,所依赖的设备全部加载完毕。master和component。master是设备树中的 “超级设备(superdevice)”,负责管理该超级设备下的"普通"设备。component是由master管理的普通设备,需要先初始化。
写文章

热门文章

  • linux内核 compoent框架分析和使用(基于zynq mpsoc) 1611
  • sourceinsight 中加入工程文件夹是空的 1277
  • 定义结构体时候初始化引起的问题 896
  • Buildroot |自定义overlayfs 429
  • 一个简单的预构建库使用 328

分类专栏

  • buildroot 1篇
  • 嵌入式C 3篇
  • 嵌入式 4篇

最新评论

  • linux内核 compoent框架分析和使用(基于zynq mpsoc)

    冰小忆: probe先后顺序不影响的,主要是master 依赖条件全部满足,才能调用bind,顺序是按照设备树解析的顺序进行bind的。

  • linux内核 compoent框架分析和使用(基于zynq mpsoc)

    fightingup: 有个疑问,component_master_add_with_match前必须保证master需要的component设备都必须创建成功,component_match_add 和 component_master_add_with_match都是在设备的probe中都用的,那是怎么保证他们的时序呢?(component 添加的probe需要在master 设备的probe前都用完)

  • linux内核 compoent框架分析和使用(基于zynq mpsoc)

    fightingup: 关于都用component的bind的顺序从上面讲的来看是和__component_match_add添加的顺利保持一致的,但是各个component添加的顺序应该是不保序的,对于master来说怎么保证各个component调用bind的顺序呢?

  • linux内核 compoent框架分析和使用(基于zynq mpsoc)

    fightingup: component 和 master的关系与内核中device和driver有点像,都是通过match去相互匹配,任意一个加入都会触发另外一个的主动probe,然后匹配最接近的driver或device,最终实现驱动程序的安装。

大家在看

  • Java Deeplearning4j:数据加载与预处理(一) 440
  • C++ 解析 RDP 协议
  • 基于Node.js+vue在线毕设选题系统(开题+程序+论文) 计算机毕业设计 483
  • 如何在C++中实现RDP协议的功能数据处理?
  • MySQL --数据类型

最新文章

  • Buildroot |自定义overlayfs
  • sourceinsight 中加入工程文件夹是空的
  • C中break,continue,returen在循环中的区别,及记录在这写出的bug
2023年1篇
2022年1篇
2020年4篇

目录

目录

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家民权制作玻璃钢雕塑公司哪家好哪里有商场美陈下城区玻璃钢雕塑企业玻璃钢雕塑清单珠海长隆玻璃钢雕塑水母商场美陈厂家浙江佛像玻璃钢雕塑哪家便宜上海园林玻璃钢雕塑厂家牙膏商场美陈济南抽象玻璃钢雕塑宁波玻璃钢雕塑厂家报价上饶特色玻璃钢雕塑市场公仔玻璃钢动物雕塑代理商宿州步行街玻璃钢雕塑制作北京开业商场美陈销售厂家商场环境美陈项目湛江玻璃钢雕塑绚丽非凡常熟商场美陈装饰西藏玻璃钢卡通雕塑专业设计定做舟山玻璃钢陶瓷雕塑制作苏州玻璃钢雕塑摆件多少钱周年庆典商场美陈制造运动商场美陈葡萄玻璃钢雕塑广告文案玻璃钢雕塑卡通造价武威彩色玻璃钢雕塑厂家花木兰玻璃钢雕塑玻璃钢雪糕雕塑厂南宁创意玻璃钢雕塑价位宿迁商场美陈报价香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化