本节笔记主要学习了Linux设备树相关知识点,由于内容较多,打算分两天进行总结。今天是第二天,着重学习Linux设备树后几节的内容,主要包括如何创建小型模板设备树、设备树在系统中的体现、特殊节点、Linux内核解析DTB文件、绑定信息文档以及常用的OF函数。
本节思维导图内容如下:

假设以 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 文件,在里面输入如下所示内容:
- / {
- 2 compatible = "fsl,imx6ull-alientek-evk", "fsl,imx6ull";
- 3 }
之后,在这个框架基础上,将上面列出的内容一点点添加进来。
1.添加cpus节点
2.添加soc节点
3.添加ocram节点
4.添加aips1、aips2、aips3节点
5.添加ecspi1、usbotg1和rngb这三个外设控制节点
- 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", "imxrng";
- 74 reg = <0x02284000 0x4000>;
- 75 };
- 76 }
- 77 }
- 78 }
Linux 内核启动的时候会解析设备树中各个节点的信息,并且在根文件系统的/proc/devicetree 目录下根据节点名字创建不同文件夹,如下:
1.根节点“/”各个属性根节点属性表现为一个个的文件。
/proc/device-tree 目录就是设备树在根文件系统中的体现,同样是按照树形结构组织的,进
入/proc/device-tree/soc 目录中就可以看到 soc 节点的所有子节点,如图:

和根节点“ /”一样,图 中的所有文件分别为 soc 节点的属性文件和子节点文件夹。
内容如下:
- 18 aliases {
- 19 can0 = &flexcan1;
- 20 can1 = &flexcan2;
- 21 ethernet0 = &fec1;
- 22 ethernet1 = &fec2;
- 23 gpio0 = &gpio1;
- 24 gpio1 = &gpio2;
- ......
- 42 spi0 = &ecspi1;
- 43 spi1 = &ecspi2;
- 44 spi2 = &ecspi3;
- 45 spi3 = &ecspi4;
- 46 usbphy0 = &usbphy1;
- 47 usbphy1 = &usbphy2;
- 48 };
aliases 节点的主要功能就是定义别名,定义别名的目的就是为了方便访问节点。不过,推荐使用&label 的形式来访问节点。
chosen 并不是一个真实的设备, chosen 节点主要是为了 uboot 向 Linux 内核传递数据,重
点是 bootargs 参数。一般.dts 文件中 chosen 节点通常为空或者内容很少。
一切的源头,来源于如下命令:
bootz 80800000 – 83000000
do_bootz 函数就会执行,然后一切就按照下图中所示的流程开始运行。

一图即可说明,如下:

路径为:Linux 源码目录/Documentation/devicetree/bindings
Linux 内核给我们提供了一系列的函数来获取设备树中的节点或者属性信息,这一系列的函数都有一个统一的前缀“ of_”,所以在很多资料里面也被叫做 OF 函数。这些 OF 函数原型都定义在 include/linux/of.h 文件中。
Linux 内核使用 device_node 结构体来描述一个节点,此结构体定义在文件 include/linux/of.h 中。
教程中在该部分给出了很多的OF函数,在这里不一一列举,通过其名字基本也可以判断出来其基本功能。
本笔记为Linux根文件的后半部分内容,主要介绍了如何创建小型模板设备树、设备树在系统中的体现、特殊节点、Linux内核解析DTB文件、绑定信息文档以及常用的OF函数。
说点题外话,昨天其实是很忙的一天,一度认为昨天的更新是不能继续的,并为此懊恼了挺长时间。等忙完手动的事情再返回到书桌时,发现也许并没有我想的那么糟糕。虽然昨天是更新了,但是更新的内容中后面有些内容是空着的。可是,即使是这样,也比我原本预料的情况要好很多。所以,有时候,有些事情,原本没有自己预料的那么糟糕。有些事情看起来不可能实现,但当自己真正开始做的时候,就已经成功了一半,不是吗?与大家共勉。
Linux版本号4.1.15 芯片I.MX6ULL
本文为参考正点原子开发板配套教程整理而得,仅用于学习交流使用,不得用于商业用途。