1、设备树
1.1、概念
在裸机驱动程序里,比如W25QXX、SPI,速度都是在.c文件中写死的,板级信息都写到.c文件中,导致linux内核臃肿。因此 将板子信息做成独立的格式,文件扩展名为.dts。一个平台或者机器对应一个.dts。
一般.dts 描述板级信息(也就是开发板上有哪些 IIC 设备、SPI 设备等),.dtsi 描述 SOC 级信息(也就是 SOC 有几个 CPU、主频是多少、各个外设控制器信息等)。
1.2、DTS、DTB 和 DTC
.dts相当于.c,就是DTS源码文件。
DTC工具相当于gcc编译器,将.dts编译成.dtb。
.dtb相当于bin文件,或可执行文件。
进入Ubuntu中
cd linux/IMX6ULL/linux/linux-imx-rel-imx_4.1.15_2.1.0_ga_alientek/ // 进入linux内核目录里
make dtbs//编译所有的dts文件
cd arch/arm/boot/dts -l //查看所有的.dtb文件
ls imx6ull-alientek-emmc.dts -l
cd linux/IMX6ULL/linux/linux-imx-rel-imx_4.1.15_2.1.0_ga_alientek/ // 进入linux内核目录里
make imx6ull-alientek-emmc.dtb//编译一个dtb文件
基于 ARM 架构的 SOC 有很多种,一种 SOC 又可以制作出很多款板子,每个板子都有一个对应的 DTS 文件,怎么确定编译的是哪一个文件呢?打开arch/arm/boot/dts/Makefile,里面有imx6ull-alientek-emmc.dtb、imx6ull-alientek-nand.dtb文件。这两个文件是给正点原子的 I.MX6U-ALPHA 开发板移植Linux 系统的时候添加的设备树。
2、DTS语法
2.1、分析
在linux源码中找到imx6ull-alientek-emmc.dts文件并打开,
12 #include <dt-bindings/input/input.h>
13 #include "imx6ull.dtsi"
第 12 行,使用“#include”来引用“input.h”这个.h 头文件。
第 13 行,使用“#include”来引用“imx6ull.dtsi”这个.dtsi 头文件。
打开imx6ull.dtsi文件,描述 I.MX6ULL 这颗 SOC 的内部外设信息,共有的信息,有SOC、CPU等,SOC中又有busfreq、aips1、aips2等,aips2包括IIC1、IIC2等,但是I2C1中又没有我们想要的具体的设备,这个时候可以去imx6ull-alientek-emmc.dts中找到&i2c1,这样就找到我们所需要的了,比如:mag3110。mag3110这个设备也有一些属性。
在imx6ull-alientek-emmc.dts文件中,斜杠表示根目录,根目录里面是子节点,里面放哪些子节点呢?这些事情由半导体厂商决定的,基本上都在.dtsi中。.dtsi包含了skeleton.dtsi文件。说明:这三个文件都有”/“,不是3个根节点,而是一个根节点。
//imx6ull-alientek-emmc.dts
/dts-v1/;
#include .h
#include imx6ull.dtsi
/{
//斜杠表示根目录,根目录里面是子节点
model = "Freescale i.MX6 ULL 14x14 EVK Board";
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
chosen{
};
memory{
};
reserved-memory{
};
backlight{
};
pxp_v412{
};
regulators{
};
sound{
};
spi4{
};
};
在skeleton.dtsi中:
/ {
#address-cells = <1>;
#size-cell = <1>;
chosen{
};
aliases{
};
memory {
device_type = "memory"; reg = <0 0>;};
};
在imx6ull-alientek-emmc.dts中也有一个memory,很明显imx6ull-alientek-emmc.dts这个里面的值把0 0替换掉了。
在imx6ull.dtsi中的根目录下有一个aliases节点,将里面的内容添加到imx6ull-alientek-emmc.dts中。
此时的文件如下:
/dts-v1/;
#include .h
#include imx6ull.dtsi
/{
/* skeleton.dtsi */
#address-cells = <1>;
#size-cell = <1>;
chosen{
stdout-path = &uart1;
};
aliases{
can0 = &flexcan1;
...
};
memory {
device_type = "memory";
reg = <0x80000000 0x20000000>;
};
cpu