dts设备树详解之设备树规范

dts文件布局(layout):
/dts-v1/;        // 第一行表示这个dts文件的版本
[memory reservations]    // 格式为:/memreserve/ <address> <length>;
/{
    [property definitions]
    [child nodes]
};

第一行表示这个dts文件的版本;
第二行表示的是保存的内存区域:如果你的板子的内存有1G大小,想留一块区域留做它用(比如拿来用作共享内存区域空间)
而不想全部都给内核使用的话,就可以使用该定义。如果你想让内核使用全部的内存的花,可以省略该选项。
example:
        memory@0x40000{
            reg = <0x40000,0x39c00000>;        // 留100M的大小用作共享内存区域,0x39c00000=924M大小给内核使用
        };

“/”代表这个设备树的起点--根;根下面会定义一些属性和子节点,子节点下面又可以再定义属性和子节点;
通过这些属性和节点,来描述该设备树是什么设备树(例如是JZ2440设备树还是mini2440设备树)同时描述该设备平台包含的外部硬件信息。

(1) DTS语法:
Devicetree node格式:
[label:] node-name[@unit-address] {
    [properties definitions]
    [child nodes]
};

属性的定义格式有以下两种:
Property格式1:
[label:] property-name = value;

Property的value取值只有3种:
1.arrays of cells(1个或多个32位数据, 64位数据使用2个32位数据表示)
   property-name = <1 0x3 0x123>
2.string(字符串)
   property-name = "string"
3.bytestring(1个或多个字节,16进制表示)
   property-name = [00 11 22]  // 11是0x11(16进制表示)
   property-name = [001122]  // byte之间的空格可以省略,取两位组成一个byte

Property格式2(没有值):
[label:] property-name;

示例:
a. Arrays of cells : cell就是一个32位的数据
interrupts = <17 0xc>;

b. 64bit数据使用2个cell来表示:
clock-frequency = <0x00000001 0x00000000>;

c. A null-terminated string (有结束符的字符串):
compatible = "simple-bus";

d. A bytestring(字节序列) :
local-mac-address = [00 00 12 34 56 78];  // 每个byte使用2个16进制数来表示
local-mac-address = [000012345678];       // 每个byte使用2个16进制数来表示

e. 可以是各种值的组合, 用逗号隔开:
compatible = "ns16550", "ns8250";
example = <0xf00f0000 19>, "a strange property format";


设备节点的定义:
Devicetree node格式:
[label:] node-name[@unit-address] {
    [properties definitions]
    [child nodes]
};

我们在访问某个设备节点时,是通过它们的设备节点名来区分不同的设备节点,
如果同一级别下存在两个相同的设备节点名,可以在设备节点名后加@address来区分不同的设备。

注意:同一个级别下的两个节点名不能相同,或者说任意一个节点的全路径不能够相同。
例如有两块不同大小的内存:
/ {
    model = "SMDK24440";
    compatible = "samsung,smdk2440";

    #address-cells = <1>;
    #size-cells = <1>;

    /* @后面加地址,为了让设备节点名彼此不同 */
    memory@30000000 {    // 全路径为/memory@30000000
        device_type = "memory";
        reg =  <0x30000000 0x4000000>;

        memory@30000000 {    // 全路径为/memory@30000000/memory@30000000
            device_type = "memory";
            reg =  <0x30000000 0x4000000>;
        };
    };
    memory@0 {    // 全路径为/memory@0
        device_type = "memory";
        reg =  <0 4096>;
    };
};

(2) 特殊的、默认的属性:
a. 根节点:
#address-cells   // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells      // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)
compatible       // 定义一系列的字符串, 用来指定内核中哪个machine_desc可以支持本设备
                 // 即这个板子兼容哪些平台
                 // uImage : 可以支持smdk2410 smdk2440 mini2440这些单板     ==> 每一种单板在内核里面都有对应的machine_desc(里面含有不同的初始化函数等)         
                 
model            // 咱这个板子是什么
                 // 比如有2款板子配置基本一致, 它们的compatible是一样的
                 // 那么就通过model来分辨这2款板子

b. /memory
device_type = "memory";
reg             // 用来指定内存的地址、大小

c. /chosen
bootargs        // 内核command line参数, 跟u-boot中设置的bootargs作用一样

d. /cpus
/cpus节点下有1个或多个cpu子节点, cpu子节点中用reg属性用来标明自己是哪一个cpu
所以 /cpus 中有以下2个属性:
#address-cells   // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)

#size-cells      // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)
                 // 必须设置为0


e. /cpus/cpu*
device_type = "cpu";
reg             // 表明自己是哪一个cpu


(4) 引用其他节点:
a. phandle : // 节点中的phandle属性, 它的取值必须是唯一的(不要跟其他的phandle值一样)

pic@10000000 {
    phandle = <1>;
    interrupt-controller;
};

another-device-node {
    interrupt-parent = <1>;   // 使用phandle值为1来引用上述节点
};

b. label:

PIC: pic@10000000 {
    interrupt-controller;
};

another-device-node {
    interrupt-parent = <&PIC>;   // 使用label来引用上述节点,
                                 // 使用lable时实际上也是使用phandle来引用,
                                 // 在编译dts文件为dtb文件时, 编译器dtc会在dtb中插入phandle属性
};
======================================================================================
PIC: pic@10000000 {
    phandle = <xxx>;
    interrupt-controller;
};

another-device-node {
    interrupt-parent = <xxx>;   // 使用label来引用上述节点,
                                 // 使用lable时实际上也是使用phandle来引用,
                                 // 在编译dts文件为dtb文件时, 编译器dtc会在dtb中插入phandle属性
};
======================================================================================

注意:引用不能写在根节点里面,必须放在根节点外面。
例如以下写法是错误的:
/{
    &PIC{
    };
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章