【u-boot】u-boot对设备树的节点解析(转)
1,设备树的引入
2,uboot本身对设备树的支持
3,对uboot中设备树节点解析代码的分析
(1)上一篇文章中提到函数 dm_init_and_scan(bool pre_reloc_only) 中有对设备树节点解析的函数dm_extended_scan_fdt()该函数的主要作用就是扫描设备树中的节点,并创立对应的设备驱动等结构的绑定工作。
先看对应的代码
int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only)
{
ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
//顾名思义,该函数就是扫描设备树并与设备驱动建立联系
ret = dm_scan_fdt_ofnode_path("/clocks", pre_reloc_only);
ret = dm_scan_fdt_ofnode_path("/firmware", pre_reloc_only);
//上面这两个该函数扫描clocks节点和firmware节点
}
重点看第一个函数的具体实现过程
int dm_scan_fdt(const void *blob, bool pre_reloc_only)
{
#if CONFIG_IS_ENABLED(OF_LIVE)
if (of_live_active())
return dm_scan_fdt_live(gd->dm_root, gd->of_root,
pre_reloc_only);
else
#endif
return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only);
}
由于没有定义OF_LIVE宏,所以该函数最终调用的是dm_scan_fdt_node函数,那么接下来看该函数的实现过程
tatic int dm_scan_fdt_node(struct udevice *parent, const void *blob,
int offset, bool pre_reloc_only)
{
int ret = 0, err;
//从偏移offset处开始一个个的扫描节点(node)
for (offset = fdt_first_subnode(blob, offset); offset > 0; offset = fdt_next_subnode(blob, offset))
{
const char *node_name = fdt_get_name(blob, offset, NULL);
/*chosen或者firmware节点本身不是一个设备,但是有可能包含其他设备节点,
扫描其子节点*/
if (!strcmp(node_name, "chosen") ||
!strcmp(node_name, "firmware")) {
pr_debug("parsing subnodes of \"%s\"\n", node_name);
err = dm_scan_fdt_node(parent, blob, offset,
pre_reloc_only);
if (err && !ret)
ret = err;
continue;//没有子节点的话则继续扫描下一个节点
}
if (!fdtdec_get_is_enabled(blob, offset)) {//忽略失能设备
pr_debug(" - ignoring disabled device\n");
continue;
}
err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL,
pre_reloc_only);
if (err && !ret) {
ret = err;
debug("%s: ret=%d\n", node_name, ret);
}
}
if (ret)
dm_warn("Some drivers failed to bind\n");
return ret;
}
int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
bool pre_reloc_only)
{
struct driver *driver = ll_entry_start(struct driver, driver);
const int n_ents = ll_entry_count(struct driver, driver);
const struct udevice_id *id;
struct driver *entry;
struct udevice *dev;
bool found = false;
const char *name, *compat_list, *compat;
int compat_length, i;
int result = 0;
int ret = 0;
if (devp)
*devp = NULL;
name = ofnode_get_name(node);
pr_debug("bind node %s\n", name);
compat_list = ofnode_get_property(node, "compatible", &compat_length);
if (!compat_list) {
if (compat_length == -FDT_ERR_NOTFOUND) {
pr_debug("Device '%s' has no compatible string\n",
name);
return 0;//这里直接返回,设备能bind的话,需要设备节点有 compatible 属性
}
dm_warn("Device tree error at node '%s'\n", name);
return compat_length;
}
//遍历compatible 字符串列表
for (i = 0; i < compat_length; i += strlen(compat) + 1) {
compat = compat_list + i;
pr_debug(" - attempt to match compatible string '%s'\n",
compat);
for (entry = driver; entry != driver + n_ents; entry++) {
ret = driver_check_compatible(entry->of_match, &id,
compat);
if (!ret)//遍历driver段表,找到相对应的driver
break;
}
if (entry == driver + n_ents)
continue;
if (pre_reloc_only) {
if (!dm_ofnode_pre_reloc(node) &&
!(entry->flags & DM_FLAG_PRE_RELOC))
return 0;
}
pr_debug(" - found match at '%s'\n", entry->name);
ret = device_bind_with_driver_data(parent, entry, name,
id->data, node, &dev);
if (ret == -ENODEV) {
pr_debug("Driver '%s' refuses to bind\n", entry->name);
continue;
}
if (ret) {
dm_warn("Error binding driver '%s': %d\n", entry->name,
ret);
return ret;
} else {
found = true;
if (devp)
*devp = dev;
}
break;
}
if (!found && !result && ret != -ENODEV)
pr_debug("No match for node '%s'\n", name);
return result;
}
函数device_bind_with_driver_data()最终调用的是device_bind_common()函数。
————————————————
版权声明:本文为CSDN博主「liuduanfei」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/A_orz_/article/details/100657963
【u-boot】u-boot对设备树的节点解析(转)的更多相关文章
- 宋牧春: Linux设备树文件结构与解析深度分析(2) 【转】
转自:https://mp.weixin.qq.com/s/WPZSElF3OQPMGqdoldm07A 作者简介 宋牧春,linux内核爱好者,喜欢阅读各种开源代码(uboot.linux.ucos ...
- 我眼中的Linux设备树(二 节点)
二 节点(node)的表示首先说节点的表示方法,除了根节点只用一个斜杠"/"表示外,其他节点的表示形式如"node-name@unit-address".@前边 ...
- Linux设备树(二 节点)
二 节点(node)的表示 首先说节点的表示方法,除了根节点只用一个斜杠“/”表示外,其他节点的表示形式如“node-name@unit-address”.@前边是节点名字,后边是节点地址.节点名字的 ...
- 宋牧春: Linux设备树文件结构与解析深度分析(1) 【转】
转自:https://mp.weixin.qq.com/s/OX-aXd5MYlE_YoZ3p32qWA 作者简介 宋牧春,linux内核爱好者,喜欢阅读各种开源代码(uboot.linux.ucos ...
- linux 设备树及节点引用【转】
本文转载自:http://blog.csdn.net/KjfureOne/article/details/51972854 1.ARM Linux社区为什么要引入设备树 Linux之父Linus To ...
- Linux设备树文件结构与解析深度分析
Copy from :https://blog.csdn.net/woyimibayi/article/details/77574736 正文开始 1. Device Tree简介 设备树就是描述单板 ...
- 基于tiny4412的Linux内核移植 -- 设备树的展开
作者信息 作者: 彭东林 邮箱:pengdonglin137@163.com QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本 ...
- 基于tiny4412的Linux内核移植 -- 设备树的展开【转】
转自:https://www.cnblogs.com/pengdonglin137/p/5248114.html#_lab2_3_1 阅读目录(Content) 作者信息 平台简介 摘要 正文 一.根 ...
- 最新内核3.4)Linux 设备树加载I2C client adapter 的流程(内核3.4 高通)【转】
转自:https://blog.csdn.net/lsn946803746/article/details/52515225 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转 ...
随机推荐
- Fabric Raft机制理解
为了不被无缘无故甩锅锅,这个我要好好理解下.
- Oracle通过正则表达式分割字符串 REGEXP_SUBSTR
REGEXP_SUBSTR函数格式如下: function REGEXP_SUBSTR(string, pattern, position, occurrence, modifier) string ...
- Linux系列(11):之bash进阶与数据流导向、管线命令
1.万用字符与特殊字符 在bash的环境下有一个特别有用的功能,那就是万用字符!下面展示常见的万用字符: 1.万用字符 除了万用字符还有一些其他的特殊字符,接下来显示特殊字符. 2.特殊字符 2.数据 ...
- 3d长方体
html <div class="main"> <div class="a1">1</div> <div class= ...
- laravel-admin关联查询问题解决办法
文档是这么说的: 按照文档上来,没有成功,网上找了好久,说是没有在模型中关联,关联之后的运行结果是这样的: 还是没有成功啊,仔细研究返现是这里写错了,whereHas后面跟的是model中的方法名,而 ...
- Autofac通过配置的方式
autofac是比较简单易用的IOC容器.下面我们展示如何通过json配置文件,来进行控制反转. 需要用到以下程序集.可以通过nugget分别安装 Microsoft.Extensions.Confi ...
- A Pythonic Card Deck: __len__ & __getitem__ & for 循环的嵌套
1. 列表生成式的嵌套 for 循环: 示例如下: li1 = range(1,6) li2 = list("ABC") # list("ABC") 的结果为 ...
- 带她来看Frozen 2
- Ubuntu12.04+Caffe (+OpenCV+CPU-only)
经过一天的努力发现12.04 的pcre的库太低了, 要解决这个bug只能升级系统到16.04 麻蛋!!! 1. 下载大神MTCNN 源码,内含caffe https://github.co ...
- python爬虫redis-ip代理池搭建几十万的ip数据--可以使用
from bs4 import BeautifulSoupimport requests,os,sys,time,random,redisfrom lxml import etreeconn = re ...