转自:https://mp.weixin.qq.com/s/WPZSElF3OQPMGqdoldm07A

作者简介

宋牧春,linux内核爱好者,喜欢阅读各种开源代码(uboot、linux、ucos、rt-thread等),对于优秀的代码框架及其痴迷。现就职于一家手机研发公司,任职Android BSP开发工程师。

正文开始

前情提要:

宋牧春: Linux设备树文件结构与解析深度分析(1)

征稿和征稿奖励名单:

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) 【转】的更多相关文章

  1. 宋牧春: Linux设备树文件结构与解析深度分析(1) 【转】

    转自:https://mp.weixin.qq.com/s/OX-aXd5MYlE_YoZ3p32qWA 作者简介 宋牧春,linux内核爱好者,喜欢阅读各种开源代码(uboot.linux.ucos ...

  2. Linux设备树文件结构与解析深度分析

    Copy from :https://blog.csdn.net/woyimibayi/article/details/77574736 正文开始 1. Device Tree简介 设备树就是描述单板 ...

  3. Linux设备树语法详解

    概念 Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.在设备树出现以前,所有关于设备的具体信息都要写在驱动里,一旦外围设备变化,驱动代码就要重写.引入了设备树之后,驱动代 ...

  4. Linux设备树语法详解【转】

    转自:http://www.cnblogs.com/xiaojiang1025/p/6131381.html 概念 Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.在设备 ...

  5. linux 设备树【转】

    转自:http://blog.csdn.net/chenqianleo/article/details/77779439 [-] linux 设备树 为什么要使用设备树Device Tree 设备树的 ...

  6. linux设备树语法

    设备树语法及绑定 概述 Device Tree是一种用来描述硬件的数据结构,类似板级描述语言,起源于OpenFirmware(OF). 就ARM平台来说,设备树文件存放在arch/arm/boot/d ...

  7. 【转载】Linux设备树(Device Tree)机制

    转:Linux设备树(Device Tree)机制   目录 1. 设备树(Device Tree)基本概念及作用2. 设备树的组成和使用 2.1. DTS和DTSI 2.2. DTC 2.3. DT ...

  8. Linux设备树学习

    1.概念 设备树用于实现驱动代码与设备信息相分离.驱动代码只负责处理驱动的逻辑而关于设备的具体信息存放到设备树文件中.(dts文件,编译后为dtb文件).一个dts文件对应一个ARM的machine, ...

  9. linux设备树笔记__dts基本概念及语法【转】

    转自:http://www.360doc.com/content/15/1113/11/15700426_512794532.shtml 设备树手册(Device Tree Usage)原文地址:ht ...

随机推荐

  1. 第206天:http协议终极详解---看这一篇就够了

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...

  2. 第89天:HTML5中 访问历史、全屏和网页存储API

    一.访问历史 API 通过history对象实现前进.后退和刷新之类的操作 history新增的两个方法history.replaceState()和history.pushState()方法属于HT ...

  3. 转--- 秒杀多线程第七篇 经典线程同步 互斥量Mutex

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  4. asp.net core 登录身份认证(Cookie)

    asp.net core 2最简单的登录功能 源代码在此 创建asp.net core Web Mvc项目 配置下选项 项目目录结构 在Models文件夹下新建两个实体类 public class T ...

  5. 【JavaScript&jQuery】购物车自动结算

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. BZOJ4883 棋盘上的守卫(环套树+最小生成树)

    容易想到网络流之类的东西,虽然范围看起来不太可做,不过这提供了一种想法,即将行列分别看做点.那么我们需要找一种连n+m条边的方案,使得可以从每条边中选一个点以覆盖所有点.显然每个点至少要连一条边.于是 ...

  7. 洛谷 P1560 蜗牛的旅行

    明显这是一道搜索题,其他题解写的有点复杂,我有更简便的写法 既然题目说走到不能再走,那我们就干脆一点,一条路走到黑,不到南墙不回头,一下把要走的路都走完,不但效率高,也好写,关键是大大节省了系统栈 一 ...

  8. C++解析(12):初始化列表与对象构造顺序、析构顺序

    0.目录 1.类成员的初始化 2.类中的const成员 3.对象的构造顺序 3.1 局部对象的构造顺序 3.2 堆对象的构造顺序 3.3 全局对象的构造顺序 4.对象的析构顺序 5.小结 1.类成员的 ...

  9. P4622 [COCI2012-2013#6] JEDAN

    题目背景 COCI 题目描述 有N个数排成一行(数值代表高度),最初所有的数都为零,你可以选择连续的一段等高的数,将它们都增加1(除了开头和结尾那个数)如下图表示了两次操作: 现在有一些数字看不清了, ...

  10. P2169 正则表达式

    题目背景 小Z童鞋一日意外的看到小X写了一个正则表达式的高级程序,这个正则表达式程序仅仅由字符“0”,“1”,“.”和“*”构成,但是他能够匹配出所有在OJ上都AC的程序的核心代码!小Z大为颇感好奇, ...