dts文件解读

/ {
compatible = "acme,coyotes-revenge";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "arm,cortex-a9";
reg = <0>;
};cpu@1 {
compatible = "arm,cortex-a9";
reg = <1>;
};
};
serial@101f0000 {
compatible = "arm,pl011";
reg = <0x101f0000 0x1000 >;
interrupts = < 1 0 >;
};
serial@101f2000 {
compatible = "arm,pl011";
reg = <0x101f2000 0x1000 >;
interrupts = < 2 0 >;
};
gpio@101f3000 {
compatible = "arm,pl061";
reg = <0x101f3000 0x1000
0x101f4000 0x0010>;
interrupts = < 3 0 >;
};
intc: interrupt-controller@10140000 {
compatible = "arm,pl190";
reg = <0x10140000 0x1000 >;
interrupt-controller;
#interrupt-cells = <2>;
};
spi@10115000 {
compatible = "arm,pl022";
reg = <0x10115000 0x1000 >;
interrupts = < 4 0 >;
};
external-bus {
#address-cells = <2>
#size-cells = <1>;
ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet
1 0 0x10160000 0x10000 // Chipselect 2, i2c controller
2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flash
ethernet@0,0 {
compatible = "smc,smc91c111";
reg = <0 0 0x1000>;
interrupts = < 5 2 >;
};
i2c@1,0 {
compatible = "acme,a1234-i2c-bus";
#address-cells = <1>;
#size-cells = <0>;
reg = <1 0 0x1000>;
interrupts = < 6 2 >;
rtc@58 {
compatible = "maxim,ds1338";
reg = <58>;
interrupts = < 7 3 >;
};
};
flash@2,0 {
compatible = "samsung,k8f1315ebm", "cfi-flash";
reg = <2 0 0x4000000>;};
};
}

1.compatible

上述.dts 文件中,root 结点"/"的 compatible 属性 compatible = "acme,coyotes-revenge";定义了系统的名称,它的组织形式为:<manufacturer>,<model>。Linux 内核透过 root 结点"/"的compatible 属性即可判断它启动的是什么 machine。在.dts 文件的每个设备,都有一个 compatible 属性,compatible 属性用户驱动和设备的绑定。compatible 属性是一个字符串的列表,列表中的第一个字符串表征了结点代表的确切设备,形式为"<manufacturer>,<model>",其后的字符串表征可兼容的其他设备。可以说前面的是特指,后面的则涵盖更广的范围。如在 arch/arm/boot/dts/vexpress-v2m.dtsi 中的Flash 结点:
flash@0,00000000 {
compatible = "arm,vexpress-flash", "cfi-flash";
reg = <0 0x00000000 0x04000000>,
<1 0x00000000 0x04000000>;
bank-width = <4>;

};

2.结点命名

cpus 和 cpus 的 2 个 cpu 子结点的命名,它们遵循的组织形式为:<name>[@<unit-address>],<>中的内容是必选项,[]中的则为可选项。name 是一个 ASCII 字符串,用于描述结点对应的设备类型,如 3com Ethernet 适配器对应的结点 name 宜为 ethernet,而不是

3com509。如果一个结点描述的设备有地址,则应该给出@unit-address。多个相同类型设备结点的 name 可以一样,只要 unit-address 不同即可,如本例中含有 cpu@0、cpu@1 以及serial@101f0000 与 serial@101f2000 这样的同名结点。设备的 unit-address 地址也经常在其对应结点的 reg 属性中给出。

3.Device Tree 中编码地址信息

            reg
            #address-cells
            #size-cells

其中 reg 的组织形式为 reg = <address1 length1 [address2 length2] [address3 length3] ... >,其中的每一组 address length 表明了设备使用的一个地址范围。父结点的#address-cells 和#size-cells 分别决定了子结点的 reg 属性的 address 和 length 字段的长度。在本例中,root 结点的#address-cells = <1>;和#size-cells =<1>;决定了 serial、gpio、spi 等结点的 address 和 length 字段的长度分别为 1。cpus 结点的#address-cells = <1>;和#size-cells = <0>;决定了 2 个 cpu 子结点的 address 为 1,而 length 为空,于是形成了 2 个 cpu 的 reg = <0>;和 reg = <1>;。external-bus 结点的#address-cells = <2>和#size-cells = <1>;决定了其下的 ethernet、i2c、flash 的 reg 字段形如 reg = <0 0 0x1000>;、reg = <1 0 0x1000>;和 reg = <2 0 0x4000000>;。

4.ranges 属性

root 结点的子结点描述的是 CPU 的视图,因此 root 子结点的 address 区域就直接位于CPU 的 memory 区域。但是,经过总线桥后的 address 往往需要经过转换才能对应的 CPU的 memory 映射。external-bus 的 ranges 属性定义了经过 external-bus 桥后的地址范围如何映射到 CPU 的 memory 区域。

ranges 是地址转换表,其中的每个项目是一个子地址、父地址以及在子地址空间的大小的映射。映射表中的子地址、父地址分别采用子地址空间的#address-cells 和父地址空间的#address-cells 大小。对于本例而言,子地址空间的#address-cells 为 2,父地址空间的#address-cells 值为 1,因此 0 0 0x10100000 0x10000 的前 2 个 cell 为 external-bus 后片选 0上偏移 0,第 3 个 cell 表示 external-bus 后片选 0 上偏移 0 的地址空间被映射到 CPU 的0x10100000 位置,第 4 个 cell 表示映射的大小为 0x10000。

5.中断相关

interrupt-controller – 这个属性为空,中断控制器应该加上此属性表明自己的身份;#interrupt-cells – 与#address-cells 和 #size-cells 相似,它表明连接此中断控制器的设备的interrupts 属性的 cell 大小。在整个 Device Tree 中,与中断相关的属性还包括:
interrupt-parent – 设备结点透过它来指定它所依附的中断控制器的 phandle,当结点没有指定 interrupt-parent 时,则从父级结点继承。对于本例而言,root 结点指定了 interrupt-parent = <&intc>;其对应于 intc: interrupt-controller@10140000,而 root 结点的子结点并未指定 interrupt-parent,因此它们都继承了 intc,即位于 0x10140000 的中断控制器。interrupts – 用到了中断的设备结点透过它指定中断号、触发方法等,具体这个属性含有多少个 cell,由它依附的中断控制器结点的#interrupt-cells 属性决定。而具体每个 cell 又是什么含义,一般由驱动的实现决定,而且也会在 Device Tree 的 binding 文档中说明。譬如,对于 ARM GIC 中断控制器而言,#interrupt-cells 为 3,它 3 个 cell 的具体含义Documentation/devicetree/bindings/arm/gic.txt 就有如下文字说明:

The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI
interrupts.
The 2nd cell contains the interrupt number for the interrupt type.
SPI interrupts are in the range [0-987]. PPI interrupts are in the
range [0-15].
The 3rd cell is the flags, encoded as follows:
bits[3:0] trigger type and level flags.
1 = low-to-high edge triggered
2 = high-to-low edge triggered
4 = active high level-sensitive
8 = active low level-sensitive
bits[15:8] PPI interrupt cpu mask. Each bit corresponds to each of
the 8 possible cpus attached to the GIC. A bit set to '1' indicated
the interrupt is wired to that CPU. Only valid for PPI interrupts.
另外,值得注意的是,一个设备还可能用到多个中断号。对于 ARM GIC 而言,若某设备使用了 SPI 的 168、169 号 2 个中断,而言都是高电平触发,则该设备结点的 interrupts属性可定义为:interrupts = <0 168 4>, <0 169 4>。

猜你喜欢

转载自blog.csdn.net/chm880910/article/details/80094037
DTS