宋牧春: Linux设备树文件结构与解析深度分析(2) 【转】
转自:https://mp.weixin.qq.com/s/WPZSElF3OQPMGqdoldm07A
作者简介
宋牧春,linux内核爱好者,喜欢阅读各种开源代码(uboot、linux、ucos、rt-thread等),对于优秀的代码框架及其痴迷。现就职于一家手机研发公司,任职Android BSP开发工程师。
正文开始
前情提要:
征稿和征稿奖励名单:
Linuxer-"Linux开发者自己的媒体"第二月稿件录取和赠书名单
Linuxer-"Linux开发者自己的媒体"首月稿件录取和赠书名单
6. platform_device和device_node绑定
经过以上解析,DeviceTree的数据已经全部解析出具体的struct device_node和struct property结构体,下面需要和具体的device进行绑定。首先讲解platform_device和device_node的绑定过程。在arch/arm/kernel/setup.c文件中,customize_machine()函数负责填充struct platform_device结构体。函数调用过程如图8所示。
图8 platform_device生成流程图
代码分析如下:
const struct of_device_id of_default_bus_match_table[] = { { .compatible = "simple-bus", }, { .compatible = "simple-mfd", }, #ifdef CONFIG_ARM_AMBA { .compatible = "arm,amba-bus", }, #endif /* CONFIG_ARM_AMBA */ {} /* Empty terminated list */ }; int of_platform_populate(struct device_node *root, const struct of_device_id *matches, const struct of_dev_auxdata *lookup, struct device *parent) { struct device_node *child; int rc = 0; /* 获取根节点 */ root = root ? of_node_get(root) : of_find_node_by_path("/"); if (!root) return -EINVAL; /* 为根节点下面的每一个节点创建platform_device结构体 */ for_each_child_of_node(root, child) { rc = of_platform_bus_create(child, matches, lookup, parent, true); if (rc) { of_node_put(child); break; } } /* 更新device_node flag标志位 */ of_node_set_flag(root, OF_POPULATED_BUS); of_node_put(root); return rc; } static int of_platform_bus_create(struct device_node *bus, const struct of_device_id *matches, const struct of_dev_auxdata *lookup, struct device *parent, bool strict) { const struct of_dev_auxdata *auxdata; struct device_node *child; struct platform_device *dev; const char *bus_id = NULL; void *platform_data = NULL; int rc = 0; /* 只有包含"compatible"属性的node节点才会生成相应的platform_device结构体 */ /* Make sure it has a compatible property */ if (strict && (!of_get_property(bus, "compatible", NULL))) { return 0; } /* 省略部分代码 */ /* * 针对节点下面得到status = "ok" 或者status = "okay"或者不存在status属性的 * 节点分配内存并填充platform_device结构体 */ dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent); if (!dev || !of_match_node(matches, bus)) return 0; /* 递归调用节点解析函数,为子节点继续生成platform_device结构体,前提是父节点 * 的“compatible” = “simple-bus”,也就是匹配of_default_bus_match_table结构体中的数据 */ for_each_child_of_node(bus, child) { rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict); if (rc) { of_node_put(child); break; } } of_node_set_flag(bus, OF_POPULATED_BUS); return rc; } |
总的来说,当of_platform_populate()函数执行完毕,kernel就为DTB中所有包含compatible属性名的第一级node创建platform_device结构体,并向平台设备总线注册设备信息。如果第一级node的compatible属性值等于“simple-bus”、“simple-mfd”或者"arm,amba-bus"的话,kernel会继续为当前node的第二级包含compatible属性的node创建platform_device结构体,并注册设备。Linux系统下的设备大多都是挂载在平台总线下的,因此在平台总线被注册后,会根据of_root节点的树结构,去寻找该总线的子节点,所有的子节点将被作为设备注册到该总线上。
7. i2c_client和device_node绑定
经过customize_machine()函数的初始化,DTB已经转换成platform_device结构体,这其中就包含i2c adapter设备,不同的SoC需要通过平台设备总线的方式自己实现i2c adapter设备的驱动。例如:i2c_adapter驱动的probe函数中会调用i2c_add_numbered_adapter()注册adapter驱动,函数流执行如图9所示。
图9 i2c_client绑定流程
在of_i2c_register_devices()函数内部便利i2c节点下面的每一个子节点,并为子节点(status = “disable”的除外)创建i2c_client结构体,并与子节点的device_node挂接。其中i2c_client的填充是在i2c_new_device()中进行的,最后device_register()。在构建i2c_client的时候,会对node下面的compatible属性名称的厂商名字去除作为i2c_client的name。例如:compatible = “maxim,ds1338”,则i2c_client->name = “ds1338”。
8. Device_Tree与sysfs
kernel启动流程为start_kernel()→rest_init()→kernel_thread():kernel_init()→do_basic_setup()→driver_init()→of_core_init(),在of_core_init()函数中在sys/firmware/devicetree/base目录下面为设备树展开成sysfs的目录和二进制属性文件,所有的node节点就是一个目录,所有的property属性就是一个二进制属性文件。
宋牧春: Linux设备树文件结构与解析深度分析(2) 【转】的更多相关文章
- 宋牧春: Linux设备树文件结构与解析深度分析(1) 【转】
转自:https://mp.weixin.qq.com/s/OX-aXd5MYlE_YoZ3p32qWA 作者简介 宋牧春,linux内核爱好者,喜欢阅读各种开源代码(uboot.linux.ucos ...
- Linux设备树文件结构与解析深度分析
Copy from :https://blog.csdn.net/woyimibayi/article/details/77574736 正文开始 1. Device Tree简介 设备树就是描述单板 ...
- Linux设备树语法详解
概念 Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.在设备树出现以前,所有关于设备的具体信息都要写在驱动里,一旦外围设备变化,驱动代码就要重写.引入了设备树之后,驱动代 ...
- Linux设备树语法详解【转】
转自:http://www.cnblogs.com/xiaojiang1025/p/6131381.html 概念 Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.在设备 ...
- linux 设备树【转】
转自:http://blog.csdn.net/chenqianleo/article/details/77779439 [-] linux 设备树 为什么要使用设备树Device Tree 设备树的 ...
- linux设备树语法
设备树语法及绑定 概述 Device Tree是一种用来描述硬件的数据结构,类似板级描述语言,起源于OpenFirmware(OF). 就ARM平台来说,设备树文件存放在arch/arm/boot/d ...
- 【转载】Linux设备树(Device Tree)机制
转:Linux设备树(Device Tree)机制 目录 1. 设备树(Device Tree)基本概念及作用2. 设备树的组成和使用 2.1. DTS和DTSI 2.2. DTC 2.3. DT ...
- Linux设备树学习
1.概念 设备树用于实现驱动代码与设备信息相分离.驱动代码只负责处理驱动的逻辑而关于设备的具体信息存放到设备树文件中.(dts文件,编译后为dtb文件).一个dts文件对应一个ARM的machine, ...
- linux设备树笔记__dts基本概念及语法【转】
转自:http://www.360doc.com/content/15/1113/11/15700426_512794532.shtml 设备树手册(Device Tree Usage)原文地址:ht ...
随机推荐
- jmeter同步定时器
同步定时器是jmeter中一个比较重要的定时器,同步定时器,相当于一个储蓄池,累积一定的请求,当在规定的时间内达到一定的线程数量,这些线程会在同一个时间点一起并发,可以用来做大数据量的并发请求. 验证 ...
- 【刷题】HDU 4966 GGS-DDU
Problem Description Do you think this is a strange problem name? That is because you don't know its ...
- windows2016上如何通过攻击ETERNALBLUE获得meterpreter反弹
windows2016上如何通过攻击ETERNALBLUE获得meterpreter反弹 译:by backlion 0x00前言 当微软发布MS17-010漏洞的补丁时,该漏洞影响的范围是从Win ...
- Fox
Portal --> broken qwq Description 有n只狐狸在一起聚餐,每只狐狸都有一个年龄.按照狐狸们的习惯,坐在一起的两只狐狸的年龄之和需要是质数.现在这些狐狸们在一些圆桌 ...
- lnmp集成环境Access Denied的问题
在你的php.ini配置文件中,设置cgi.fix_pathinfo=1
- Chiaki Sequence Revisited HDU - 6304 lowbit找规律法
Problem Description Chiaki is interested in an infinite sequence a1,a2,a3,..., which is defined as f ...
- 「Django」rest_framework学习系列-渲染器
渲染器:作用于页面,JSONRenderer只是JSON格式,BrowsableAPIRenderer有页面,.AdminRenderer页面以admin形式呈现(需要在请求地址后缀添加?fromat ...
- 树的性质和dfs的性质 Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) E
http://codeforces.com/contest/782/problem/E 题目大意: 有n个节点,m条边,k个人,k个人中每个人都可以从任意起点开始走(2*n)/k步,且这个步数是向上取 ...
- 「七天自制PHP框架」应用:JSON生成器
刚刚开始学做一个WebAPP,数据查询的一般套路是通过一张PHP页面读取数据库,获得列表后“嵌写”在PHP页面中,虽然写法上丑陋至极,但也有“快糙猛”出效果的成就感,如图. 后来想想,不对啊,难道以后 ...
- Spring Boot 使用IntelliJ IDEA创建一个web开发实例(一)
.新建项目File-->New-->Project-->Spring Initializr 点击Finish,一个Spring Boot web应用就创建好了.