Device Tree 入门

1.写在前面

本文是本人在阅读了蜗窝科技的Device Tree三篇文章后的笔记,他的这几篇文章是我最近了解到的在Device Tree方面讲的比较深入细致的,非常感谢蜗窝科技为我们提供的学习机会,如果有需要,请你们去蜗窝科技。

2.Device Tree结构

kernel/arch/arm/boot/dts/skeleton.dtsi:
/ {
    #address-cells = <1>;
    #size-cells = <1>;
    cpus { };
    soc { };
    chosen { };
    aliases { };
    memory { device_type = "memory"; reg = <0 0>; };
};
kernel/arch/arm/boot/dts/qcom/skeleton.dtsi:
#include "skeleton64.dtsi"
#include 8953.h>
#include 
#include 
/ {
    model = "Qualcomm Technologies, Inc. MSM 8953";
    compatible = "qcom,msm8953";
    qcom,msm-id = <293 0x0>;
    interrupt-parent = <&intc>;

    chosen {
        bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1";
    };

    reserved-memory {
        #address-cells = <2>;
        #size-cells = <2>;
        ranges;

        other_ext_mem: other_ext_region@0 {
            compatible = "removed-dma-pool";
            no-map;
            reg = <0x0 0x83300000 0x0 0x3800000>;
        };

        modem_mem: modem_region@0 {
            compatible = "removed-dma-pool";
            no-map-fixup;
            reg = <0x0 0x86c00000 0x0 0x5600000>;
        };

        reloc_mem: reloc_region@0 {
            compatible = "removed-dma-pool";
            no-map;
            reg = <0x0 0x8c200000 0x0 0x1800000>;
        };

        venus_mem: venus_region@0 {
            compatible = "shared-dma-pool";
            reusable;
            alloc-ranges = <0x0 0x80000000 0x0 0x10000000>;
            alignment = <0 0x400000>;
            size = <0 0x0800000>;
        };

        secure_mem: secure_region@0 {
            compatible = "shared-dma-pool";
            reusable;
            alignment = <0 0x400000>;
            size = <0 0x09800000>;
        };

        qseecom_mem: qseecom_region@0 {
            compatible = "shared-dma-pool";
            reusable;
            alignment = <0 0x400000>;
            size = <0 0x1000000>;
        };

        adsp_mem: adsp_region@0 {
            compatible = "shared-dma-pool";
            reusable;
            size = <0 0x400000>;
        };

        dfps_data_mem: dfps_data_mem@90000000 {
               reg = <0 0x90000000 0 0x1000>;
               label = "dfps_data_mem";
        };

        cont_splash_mem: splash_region@0x90001000 {
            reg = <0x0 0x90001000 0x0 0x13ff000>;
            label = "cont_splash_mem";
        };

        gpu_mem: gpu_region@0 {
            compatible = "shared-dma-pool";
            reusable;
            alloc-ranges = <0x0 0x80000000 0x0 0x10000000>;
            alignment = <0 0x400000>;
            size = <0 0x800000>;
        };
    };

    aliases {
        /* smdtty devices */
        smd1 = &smdtty_apps_fm;
        smd2 = &smdtty_apps_riva_bt_acl;
        smd3 = &smdtty_apps_riva_bt_cmd;
        smd4 = &smdtty_mbalbridge;
        smd5 = &smdtty_apps_riva_ant_cmd;
        smd6 = &smdtty_apps_riva_ant_data;
        smd7 = &smdtty_data1;
        smd8 = &smdtty_data4;
        smd11 = &smdtty_data11;
        smd21 = &smdtty_data21;
        smd36 = &smdtty_loopback;
        sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
        sdhc2 = &sdhc_2; /* SDC2 for SD card */
        i2c1 = &i2c_1;
        i2c2 = &i2c_2;
        i2c3 = &i2c_3;
        i2c5 = &i2c_5;
        spi3 = &spi_3;
    };

    soc: soc { };

};
由上面的例子看出Device Tree有一下特点:
1.节点node
    1.1每个node可以包含sub node和property/value;
    1.2每个DTS都只有一个ROOT node;
    1.3一个node可以有多个sub node,但只能有一个parent node;
    1.4一个node可以包含多个property/value描述该node的具体信息;
    1.5每个node用节点名字(node name)标识,节点名字的格式是node-name@unit-address。如果该node没有reg属性(后面会描述这个property),那么该节点名字中必须不能包括@和unit-address。
2.属性/值property/value
    2.1一般属性:
    属性值表示了该设备节点的具体特性,它的值是多样性的:
    1)可能为空,即没有值的定义;
    2)可能为32bit或64bit整数值(#size-cells = <2>)或者数组(reg = <0x0 0x86c00000 0x0 0x5600000>);
    3)可能为string(label = "cont_splash_mem")或string list(compatible = "qcom,msm8953");
    2.2特殊属性:
    #address-cells = <1>;
    #size-cells = <0>;
    #类似number,#address-cells表示子节点中reg中的地址元素需要用多少个32bit值来表示,#size-cells表示子节点中reg中的大小元素需要用多少个32bit值来表示。

3.Device Tree source file语法

1.节点定义:
    [label:] node-name[@unit-address] { 
       [properties definitions];
       [child nodes];
    };
2.节点引用:
    1)直接引用:绝对路径,/node-name-1/node-name-2/node-name-N;
    2)别名引用:所有别名被定义在节点aliases中;
    3)lable引用:&lable;
3.属性定义:
    property = value;
    再次注意value的三种方式:
    1)32bit unsigned integers:#size-cells = <2>;
    2)binary data:binary-property = [0x01 0x23 0x45 0x67];
    3)string/string list:device_type = "memory";

4.dts注释

dts支持c/c++类型注释,如下方式:

    /* 多行注释 */
    /*
    dfps_data_mem: dfps_data_mem@90000000 {
        reg = <0 0x90000000 0 0x1000>;
        label = "dfps_data_mem";
    };
    */

    cont_splash_mem: splash_region@0x90001000 {
        //单行注释
        //reg = <0x0 0x90001000 0x0 0x13ff000>;
        //label = "cont_splash_mem";
    };

5.dts编译

dts的编译一般使用dtc工具,kernel源码中自带该工具,编译后在/script/dtc/目录下。
使用方法:
1.编译dts为dtb文件:

dtc -I dts -O dtb -o <dtbfilename> <dtsfilename>

2.反编译dtb为dts文件:

dtc -I dtb -O dts -o <dtsfilename> <dtbfilename>

你可能感兴趣的:(linux,内核)