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>。

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