文章目录
一、设备树概念
💦设备树(Device Tree),将这个词分开就是“设备”和“树”,描述设备树的文件叫做 DTS(Device Tree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比如CPU 数量、 内存基地址、IIC 接口上接了哪些设备、SPI 接口上接了哪些设备等等,总结来说,设备树:描述一个平台上的外设信息(设备信息)
二、DTS、DTB 和 DTC
💦设备树源文件扩展名为.dts,但是我们在移植 Linux 的时候却一直在使用.dtb 文件,那么 DTS 和 DTB 这两个文件是什么关系呢?DTS 是设备树源码文件,DTB 是将DTS 编译以后得到的二进制文件。将.c 文件编译为.o 需要用到 gcc 编译器,那么将.dts 编译为.dtb需要什么工具呢?需要用到 DTC 工具!DTC 工具源码在 Linux 内核的 scripts/dtc 目录下,
scripts/dtc/Makefile 文件内容如下:
💦DTC 工具依赖于 dtc.c、flattree.c、fstree.c 等文件,最终编译并链接出 DTC 这个文件。
1.dtb文件编译
make dtbs
💦编译所有的dtb文件。
💦单个dtb文件编译,在系统跟目录输入如下指令:
make xxx.dtb
💦注意:顶层makefile文件已经修改过才行,否则就需要加上,架构和编译器。
2.在编译的时候如何自动编译自己板子的dtb
💦在Linux中,因为会支持很多板子,就会有很多dtb文件,所以为了统一管理,通过arch/arm/boot/dts/Makefile文件来管理,在这个文件中加入自己的dtb文件就可以实现统一编译。
注意格式,不要乱按空格
三.DTS 语法
💦在DTS语法中也有头文件的说法。
1.dtsi 头文件
💦在.dts 设备树文件中,可以通过“#include”来引用.h、.dtsi 和.dts 文件。就像上图所示,所以我们在编写设备树头文件的时候最好选择.dtsi 后缀。
💦一般.dtsi 文件用于描述 SOC 的内部外设信息,比如 CPU 架构、主频、外设寄存器地址范围,比如 UART、IIC 等等。比如 imx6ull.dtsi 就是描述 I.MX6ULL 这颗 SOC 内部外设情况信息的,内容如下:时钟信息
2.语法
①DTS从‘/’开始
②从根节点‘/’开始描述设备信息
③在根节点外,以取址符开始(&cup0)向节点添加信息,添加的信息可以被新添加属性信息覆盖。
③节点的命名方式:node-name@uint-address 节点名字+单元地址
uint-address一般是外设的起始地址,有时候是IIC的设备地址,或者其他含义,具体的节点具体分析。
⑤在设备树中会遇到下面的写法:
cpu0: cpu@0
💦此写法与节点的命名方式不同,而是用“:”隔开成了两部分,“:”
前面的是节点标签(label),“:”后面的才是节点名字,格式如下所示:
label: node-name@unit-address
💦引入 label 的目的就是为了方便访问节点,可以直接通过&label 来访问这个节点,比如通过&cpu0 就可以访问“cpu@0”这个节点,而不需要输入完整的节点名字。
💦比如节点 “intc: interrupt-controller@00a01000”,节点 label 是 intc,而节点名字就很长了,为“interrupt-controller@00a01000”。很明显通过&intc 来访问“interrupt-controller@00a01000”这个节点要方便很多,所以引用label就是方便访问节点信息的。
3.设备树在系统的体现形式
💦这些外设信息可以在手册的memory中找到的。
💦系统启动后是可以在根文件系统中查看到设备树的节点信息,在目录/proc/device-tree下查看。
💦这个目录下的文件就是根目录的第一级子节点,可以在dts和dtsi文件中核对。
💦这些是节点,也是文件,是可以查看的,比如cat compatible
💦在比如soc节点,cd soc,黑色加深的是soc下的节点,没有黑色加深的是soc节点的属性信息,比如pmu就是soc的节点信息,也可以说是根目录的二级节点。
💦在dtis文件中可以看出与在根文件系统中查看的一致
💦在打开aips-bus@0210000,这里边就有i2c控制器。
💦在打开i2c@021a4000
💦在dts文件中可以看出与在根文件系统中查看的一致,
💦一般dtsi文件是描述的公共的设备信息,比如cpu,i2c控制器等,dts文件一般是添加具体的设备信息,比如wm8960芯片信息。
💦在内核在启动的时候,告诉了内核设备树的地址,所以内核是可以找到设备树并调用函数解析出来,放到/proc/device-tree/目录下。
4.创建自己的设备节点
💦在根目录按照节点格式添加自己的节点。
①编译,make dtbs
②将编译好的dtb文件复制到tftp加载目录中,因为uboot通过tftp加载的设备树和zImage文件。
③重启开发板
④cd proc/device-tree/查看节点信息。
5.特殊的节点
aliases 子节点
💦单词 aliases 的意思是“别名”,因此 aliases 节点的主要功能就是定义别名,定义别名的目的就是为了方便访问节点。不过我们一般会在节点命名的时候会加上 label,然后通过&label来访问节点,这样也很方便,而且设备树里面大量的使用&label 的形式来访问节点。
chosen 子节点
💦chosen 并不是一个真实的设备,chosen 节点主要是为了 uboot 向 Linux 内核传递命令行参数cmd line,重点是 bootargs 参数。一般.dts 文件中 chosen 节点通常为空或者内容很少,imx6ull-alientekemmc.dts 中 chosen 节点内容如下所示:
Kernel command line: console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.20:/home/che/linux/nfsfile/rootfs,proto=tcp rw ip=192.168.1.50:192.168.1.20:192.168.1.1:255.255.255.0::eth0:off
💦与uboot的 bootargs参数一致。
💦那uboot是如何将bootargs参数传递到内核呢,查看下console节点信息,发现里边竟然有bootargs参数。
💦在Linux中console节点并没有bootargs参数,那这个参数怎么来的呢,推测下应该是uboot在启动的时候像console节点里添加了这个信息。