本文我們從頭到尾編寫一個小型的設備樹文件。當然了,這個小型設備樹沒有實際的意義,做這個對的目的是為了掌握設備樹的語法。在實際產品開發中,我們是不需要完完全全的重寫一個.dts 設備樹文件,一般都是使用SOC 廠商提供好的.dts 文件,我們只需要在上面根據自己的實際情況做相應的修改即可。在編寫設備樹之前要先定義一個設備,我們就以 I.MX6ULL 這個 SOC 為例,我們需要在設備樹裡面描述的內容如下:
①、I.MX6ULL 這個Cortex-A7 架構的 32 位CPU。
②、I.MX6ULL 內部ocram,起始地址 0x00900000,大小為 128KB(0x20000)。
③、I.MX6ULL 內部 aips1 域下的 ecspi1 外設控制器,寄存器起始地址為 0x02008000,大小為 0x4000。
④、I.MX6ULL 內部 aips2 域下的 usbotg1 外設控制器,寄存器起始地址為 0x02184000,大小為 0x4000。
⑤、I.MX6ULL 內部 aips3 域下的 rngb 外設控制器,寄存器起始地址為 0x02284000,大小為 0x4000。
為了簡單起見,我們就在設備樹裡面就實現這些內容即可,首先,搭建一個僅含有根節點“/”的基礎的框架,新建一個名為 myfirst.dts 文件,在裡面輸入如下所示內容:
1 / {
2 compatible = "fsl,imx6ull-alientek-evk", "fsl,imx6ull";
3 }
設備樹框架很簡單,就一個根節點“/”,根節點裡面只有一個 compatible 屬性。我們就在這個基礎框架上面將上面列出的內容一點點添加進來。
1、添加 cpus 節點
首先添加CPU 節點,I.MX6ULL 採用Cortex-A7 架構,而且只有一個 CPU,因此只有一個cpu0 節點,完成以後如下所示:
1 / {
2 compatible = "fsl,imx6ull-alientek-evk", "fsl,imx6ull";
3
4 cpus {
5 #address-cells = <1>;
6 #size-cells = <0>; 7
8 //CPU0 節點
9 cpu0: cpu@0 {
10 compatible = "arm,cortex-a7";
11 device_type = "cpu";
12 reg = <0>;
13 };
14 };
15 }
第 4~14 行,cpus 節點,此節點用於描述 SOC 內部的所有CPU,因為 I.MX6ULL 只有一個CPU,因此只有一個 cpu0 子節點。
2、添加 soc 節點
像 uart,iic 控制器等等這些都屬於 SOC 內部外設,因此一般會創建一個叫做 soc 的父節點來管理這些SOC 內部外設的子節點,添加 soc 節點以後的 myfirst.dts 文件內容如下所示:
1 / {
2 compatible = "fsl,imx6ull-alientek-evk", "fsl,imx6ull"; 3
4 cpus {
5 #address-cells = <1>;
6 #size-cells = <0>;
7
8 //CPU0 節點
9 cpu0: cpu@0 {
10 compatible = "arm,cortex-a7";
11 device_type = "cpu";
12 reg = <0>;
13 };
14 };
15
16 //soc 節點
17 soc {
18 #address-cells = <1>;
19 #size-cells = <1>;
20 compatible = "simple-bus";
21 ranges; 22 }
23 }
第 17~22 行,soc 節點,soc 節點設置#address-cells = <1>,#size-cells = <1>,這樣 soc 子節點的 reg 屬性中起始地佔用一個字長,地址空間長度也佔用一個字長。
第 21 行,ranges 屬性,ranges 屬性為空,說明子空間和父空間地址範圍相同。
3、添加 ocram 節點
根據第②點的要求,添加 ocram 節點,ocram 是 I.MX6ULL 內部RAM,因此 ocram 節點應該是 soc 節點的子節點。ocram 起始地址為 0x00900000,大小為 128KB(0x20000),添加 ocram節點以後 myfirst.dts 文件內容如下所示:
1 / {
2 compatible = "fsl,imx6ull-alientek-evk", "fsl,imx6ull"; 3
4 cpus {
5 #address-cells = <1>;
6 #size-cells = <0>;
7
8 //CPU0 節點
9 cpu0: cpu@0 {
10 compatible = "arm,cortex-a7";
11 device_type = "cpu";
12 reg = <0>;
13 };
14 };
15
16 //soc 節點
17 soc {
18 #address-cells = <1>;
19 #size-cells = <1>;
20 compatible = "simple-bus";
21 ranges; 22
23 //ocram 節點
24 ocram: sram@00900000 {
25 compatible = "fsl,lpm-sram";
26 reg = <0x00900000 0x20000>;
27 };
28 }
29 }
第 24~27 行,ocram 節點,第 24 行節點名字@後面的 0x00900000 就是 ocram 的起始地址。第 26 行的 reg 屬性也指明瞭 ocram 內存的起始地址為 0x00900000,大小為 0x20000。
4、添加 aips1、aips2 和 aips3 這三個子節點
I.MX6ULL 內部分為三個域:aips1~3,這三個域分管不同的外設控制器,aips1~3 這三個域對應的內存範圍如表所示:
我們先在設備樹中添加這三個域對應的子節點。aips1~3 這三個域都屬於soc 節點的子節點,完成以後的myfirst.dts 文件內容如下所示:
1 / {
2 compatible = "fsl,imx6ull-alientek-evk", "fsl,imx6ull"; 3
4 cpus {
5 #address-cells = <1>;
6 #size-cells = <0>;
7
8 //CPU0 節點
9 cpu0: cpu@0 {
10 compatible = "arm,cortex-a7";
11 device_type = "cpu";
12 reg = <0>;
13 };
14 };
15
16 //soc 節點
17 soc {
18 #address-cells = <1>;
19 #size-cells = <1>;
20 compatible = "simple-bus";
21 ranges; 22
23 //ocram 節點
24 ocram: sram@00900000 {
25 compatible = "fsl,lpm-sram";
26 reg = <0x00900000 0x20000>;
27 };
28
29 //aips1 節點
30 aips1: aips-bus@02000000 {
31 compatible = "fsl,aips-bus", "simple-bus";
32 #address-cells = <1>;
33 #size-cells = <1>;
34 reg = <0x02000000 0x100000>;
35 ranges;
36 }
37
38 //aips2 節點
39 aips2: aips-bus@02100000 {
40 compatible = "fsl,aips-bus", "simple-bus";
41 #address-cells = <1>;
42 #size-cells = <1>;
43 reg = <0x02100000 0x100000>;
44 ranges;
45 }
46
47 //aips3 節點
48 aips3: aips-bus@02200000 {
49 compatible = "fsl,aips-bus", "simple-bus";
50 #address-cells = <1>;
51 #size-cells = <1>;
52 reg = <0x02200000 0x100000>;
53 ranges;
54 }
55 }
56 }
第 30~36 行,aips1 節點。第 39~45 行,aips2 節點。第 48~54 行,aips3 節點。
5、添加 ecspi1、usbotg1 和 rngb 這三個外設控制器節點
最後我們在 myfirst.dts 文件中加入 ecspi1,usbotg1 和 rngb 這三個外設控制器對應的節點,其中 ecspi1 屬於 aips1 的子節點,usbotg1 屬於 aips2 的子節點,rngb 屬於 aips3 的子節點。最終的 myfirst.dts 文件內容如下:
1 / {
2 compatible = "fsl,imx6ull-alientek-evk", "fsl,imx6ull"; 3
4 cpus {
5 #address-cells = <1>;
6 #size-cells = <0>;
7
8 //CPU0 節點
9 cpu0: cpu@0 {
10 compatible = "arm,cortex-a7";
11 device_type = "cpu";
12 reg = <0>;
13 };
14 };
15
16 //soc 節點
17 soc {
18 #address-cells = <1>;
19 #size-cells = <1>;
20 compatible = "simple-bus";
21 ranges; 22
23 //ocram 節點
24 ocram: sram@00900000 {
25 compatible = "fsl,lpm-sram";
26 reg = <0x00900000 0x20000>;
27 };
28
29 //aips1 節點
30 aips1: aips-bus@02000000 {
31 compatible = "fsl,aips-bus", "simple-bus";
32 #address-cells = <1>;
33 #size-cells = <1>;
34 reg = <0x02000000 0x100000>;
35 ranges;
36
37 //ecspi1 節點
38 ecspi1: ecspi@02008000 {
39 #address-cells = <1>;
40 #size-cells = <0>;
41 compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
42 reg = <0x02008000 0x4000>;
43 status = "disabled"; 44 };
45 }
46
47 //aips2 節點
48 aips2: aips-bus@02100000 {
49 compatible = "fsl,aips-bus", "simple-bus";
50 #address-cells = <1>;
51 #size-cells = <1>;
52 reg = <0x02100000 0x100000>;
53 ranges;
54
55 //usbotg1 節點
56 usbotg1: usb@02184000 {
57 compatible = "fsl,imx6ul-usb", "fsl,imx27-usb";
58 reg = <0x02184000 0x200>;
59 status = "disabled"; 60 };
61 }
62
63 //aips3 節點
64 aips3: aips-bus@02200000 {
65 compatible = "fsl,aips-bus", "simple-bus";
66 #address-cells = <1>;
67 #size-cells = <1>;
68 reg = <0x02200000 0x100000>;
69 ranges;
70
71 //rngb 節點
72 rngb: rngb@02284000 {
73 compatible = "fsl,imx6sl-rng", "fsl,imx-rng", "imx- rng";
74 reg = <0x02284000 0x4000>;
75 };
76 }
77 }
78 }
第 38~44 行,ecspi1 外設控制器節點。第 56~60 行,usbotg1 外設控制器節點。第 72~75 行,rngb 外設控制器節點。
至此,myfirst.dts 這個小型的模板設備樹就編寫好了,基本和 imx6ull.dtsi 很像,可以看做是 imx6ull.dtsi 的縮小版。在 myfirst.dts 裡面我們僅僅是編寫了 I.MX6ULL 的外設控制器節點,像 IIC 接口,SPI 接口下所連接的具體設備我們並沒有寫,因為具體的設備其設備樹屬性內容不同。
閱讀更多 小平頭 的文章