设备树

什么是设备树

在Linux3.x之前的内核源码中,存在大量对板级细节信息描述的代码。这些代码充斥在/arch/arm/plat-xxx和/arch/arm/mach-xxx目录。为了解决这个问题而引入设备树。 

官方对设备树的描述是,一种描述硬件资源的数据结构。它通过bootloader将硬件资源传给内核,使得内核和硬件资源描述相对独立。

设备树的主要优势:对于同一SOC的不同主板,只需更换设备树文件.dtb即可实现不同主板的无差异支持,而无需更换内核文件。

设备树组成

  设备树包含DTC(device tree compiler),DTS(device tree source和DTB(device tree blob)

DTS: dts文件是对Device Tree的描述,放置在内核的/arch/arm/boot/dts目录。一个*.dts文件对应一个ARM的machine。dts文件描述了一个板子的硬件资源。以前写在mach-xxx文件中的内容被转成了dts文件。

DTC: DTC为编译工具,它可以将.dts文件编译成.dtb文件。

DTB: DTC编译*.dts生成的二进制文件(.dtb),bootloader在引导内核时,会预先读取.dtb到内存,进而由内核解析。

设备树中还有一种文件 ------- dtsi文件,由于一个SOC可能有多个不同的电路板,而每个电路板拥有一个 .dts。这些dts势必会存在许多共同部分,为了减少代码的冗余,设备树将这些共同部分提炼保存在.dtsi文件中,供不同的dts共同使用。

语法规则

一、设备树语法

    (1)设备树节点语法

[label:] node-name[@unit-address] {    [properties definitions];    [child nodes];};
解释:

    label: 可选项,节点别名

    node-name: 节点名

    unit-address: 设备地址

    properties definitions:属性定义

    child nodes:子节点

  (2) 属性定义语法

[label:] property-name = value;[label:] property-name;
属性分为有属性值和无属性值

属性值有三种取值:

arrays of cells(1个或多个32位数据, 64位数据使用2个32位数据表示),用尖括号表示(< >)

string(字符串), 用双引号表示(" ")

bytestring(1个或多个字节),用方括号表示([ ])

 

二、特殊属性

(1)根节点

 

(2) /memory

所有设备树文件的必需节点,它定义了系统物理内存的 layout

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

(3) /chosen

传递runtime parameter

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

(4) /cpus

/cpus节点下有1个或多个cpu子节点, cpu子节点中用reg属性用来标明自己是哪一个cpu

(5) aliases

用来定义别名

aliases {    ethernet0 = &gmac;    i2c0 = &i2c0;    i2c1 = &i2c1;    i2c2 = &i2c2;  
             mshc0 = &emmc;    mshc1 = &sdmmc;    mshc2 = &sdio0;    mshc3 = &sdio1;    
             serial0 = &uart0;    serial1 = &uart1;    spi0 = &spi0;    spi1 = &spi1;  };

三、引用其他节点

(1) phandle属性引用

    节点中的phandle属性, 它的取值必须是唯一的(不要跟其他的phandle值一样)

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

 (2)使用别名(本质还是phandle)

PIC: pic@10000000 {    interrupt-controller;};
another-device-node {    interrupt-parent = <&PIC>;   // 使用label来引用上述节点   

四、包含dtsi文件

#include "rk3288-firefly.dtsi"

五、使用宏定义

六、属性重写

//rk3288.dtsihdmi: hdmi@ff980000 {    compatible = "rockchip,rk3288-dw-hdmi";    
reg = <0x0 0xff980000 0x0 0x20000>;    reg-io-width = <4>;    #sound-dai-cells = <0>; 
 rockchip,grf = <&grf>;    interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;    
clocks = <&cru  PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>;    
clock-names = "iahb", "isfr", "cec";    power-domains = <&power RK3288_PD_VIO>;    
status = "disabled";};
//rk3288-firefly.dtsi&hdmi {  ddc-i2c-bus = <&i2c5>;  status = "okay";};

上面的rk3288-firefly.dtsi包含rk3288.dtsi, 然后使用&hdmi引用rk3288.dtsi中的hdmi节点。并在原有的基础上添加ddc-i2c-bus属性,然后将status属性进行重写覆盖。这就体现了dtsi文件的价值,dtsi定义公共的部分,板级差异再进行添加或重写。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值