手把手创建一个小型模板Linux设备树

2019-11-23 14:15发布

本文我们从头到尾编写一个小型的设备树文件。当然了,这个小型设备树没有实际的意义,做这个对的目的是为了掌握设备树的语法。在实际产品开发中,我们是不需要完完全全的重写一个.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 这三个域对应的内存范围如表所示:

ec54338ec57c42289b5eb8b876f01202.jpg

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 接口下所连接的具体设备我们并没有写,因为具体的设备其设备树属性内容不同。