1:设备树:描述板级硬件信息的内容都从 Linux 内中分离开来,用一个专属的文件格式来描述,这个专属的文件就叫做设备树,文件扩展名为.dts;dtsi 描述 SOC 级信息(也就是 SOC 有几个 CPU、主频是多少、各个外设控制器信息等),一般.dts 描述板级信息(也就是开发板上有哪些 IIC 设备、SPI 设备等)

dts:设备树源文件

dtd:设备树编译后得二进制文件

dtc:编译设备树的工具

make dtbs:只是编译设备树
 
2:设备树语法
  2.1:头文件:支持.h , .dtsi , .dts文件
  2.2:设备节点:设备树是采用树形结构来描述板子上的设备信息的文件,每个设备都是一个节点,叫做设备节点,每个节点都通过一些属性信息来描述节点信息,属性就是键—值对,一般节点命名格式如下
label: node-name@unit-address

  每个节点都有不同属性,不同的属性又有不同的内容,属性都是键值对,值可以为空或任意的字节流。设备树源码中常用的几种数据形式如下所示

①、字符串 
compatible = "arm,cortex-a7";
上述代码设置 compatible 属性的值为字符串“arm,cortex-a7”。
②、32 位无符号整数
reg = <0>;
上述代码设置 reg 属性的值为 0,reg 的值也可以设置为一组值,比如:
reg = <0 0x123456 100>;
③、字符串列表
属性值也可以为字符串列表,字符串和字符串之间采用“,”隔开,如下所示:
compatible = "fsl,imx6ull-gpmi-nand", "fsl, imx6ul-gpmi-nand";
上述代码设置属性 compatible 的值为“fsl,imx6ull-gpmi-nand”和“fsl, imx6ul-gpmi-nand”。

  2.3:compatible属性:叫做“兼容性”属性;compatible 属性的值是一个字符串列表,compatible 属性用于将设备和驱动绑定起来;例如

compatible = "fsl,imx6ul-evk-wm8960","fsl,imx-audio-wm8960";

  一般驱动程序文件都会有一个 OF 匹配表,此 OF 匹配表保存着一些 compatible 值,如果设备节点的 compatible 属性值和 OF 匹配表中的任何一个值相等,那么就表示设备可以使用这个驱动,比如在文件 imx-wm8960.c 中有如下内容

 static const struct of_device_id imx_wm8960_dt_ids[] = {
 { .compatible = "fsl,imx-audio-wm8960", },
 { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, imx_wm8960_dt_ids);

 static struct platform_driver imx_wm8960_driver = {
 .driver = {
 .name = "imx-wm8960",
 .pm = &snd_soc_pm_ops,
 .of_match_table = imx_wm8960_dt_ids,
 },
 .probe = imx_wm8960_probe,
 .remove = imx_wm8960_remove,
 };

  2.4:model 属性:也是一个字符串,一般 model 属性描述设备模块信息,比如名字什么的,比如:model="wm8960-audio";

  2.5:status属性:也是字符串,字符串是设备的状态信息,具体如下

 

   2.6:#address-cells 和#size-cells 属性: 这两个属性可以用在任何拥有子节点的设备中,用于描述子节点的地址信息。#address-cells 属性值决定了子节点 reg 属性中地址信息所占用的字长(32 位),#size-

cells 属性值决定了子节点 reg 属性中长度信息所占的字长(32 位); 表明了子节点应该如何编写 reg 属性值,一般 reg 属性都是和地址有关的内容,和地址相关的信息有两种:起始地址和地址长度,reg 属性的格式一为:
reg = <address1 length1 address2 length2 address3 length3……>

  2.7:reg 属性:前面已经提到过了,reg 属性的值一般是(address,length)对。reg 属性一般用于描述设备地址空间资源信息,一般都是某个外设的寄存器地址范围信息

  2.8:ranges属性:可以为空或者按照(child-bus-address,parent-bus-address,length)格式编写的数字矩阵,ranges 是一个地址映射/转换表,ranges 属性每个项目由子地址、父地址和地址空间长度这三部分组成:

 soc { 
     compatible = "simple-bus"; 
     #address-cells = <1>;
     #size-cells = <1>;
     ranges = <0x0 0xe0000000 0x00100000>;
     serial { 
    device_type = "serial"; 9 compatible = "ns16550";
     reg = <0x4600 0x100>;
     clock-frequency = <0>;
     interrupts = <0xA 0x8>;
     interrupt-parent = <&ipic>;
     };
 };

  经过地址转换,serial 设备可以从 0xe0000000+ox4600处 开始进行读写操作

  2.9:根节点 compatible属性:设备节点的compatible属性是用来匹配内核中的驱动程序,而根节点的compatible属性是用来匹配设备的

 / { 
 model = "Freescale i.MX6 ULL 14x14 EVK Board"; 
 compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
.......
}

   2.9.1:不用设备树的话就是用machine id匹配,内核用MACHINE_START和 MACHINE_END宏来定义一个machine_desc结构体描述一个设备

   MACHINE_START宏定义如下

#define MACHINE_START(_type,_name) \ 
static const struct machine_desc __mach_desc_##_type \
 __used \ 
__attribute__((__section__(".arch.info.init"))) = { \ 
.nr = MACH_TYPE_##_type, \ 
.name = _name, #define MACHINE_END  \
 };
  上面张开后,里面有如下内容
.nr = MACH_TYPE_MX35_3DS, 
.name = "Freescale MX35PDK",

   MACH_TYPE_MX35_3DS定义在文件 定义在文件 include/generated/mach-types.h

#define MACH_TYPE_MX35_3DS 1645

   2.9.2:内核引入设备树后,,内核用DT_MACHINE_START和 MACHINE_END宏来定义一个machine_desc结构体描述一个设备;只要根节点的compatible属性值与imx6ul_dt_compat表中的任何一个值相等,那么就示 Linux内核支持此设备

   2.10:chosen节点:chosen并不是一个真实的设备, 并不是一个真实的设备,  chosen节点主要是为了uboot向 Linux内核传递数据;uboot自己在 自己在 chosen节点里面添加了bootargs属性!并且设置bootargs属性的值为bootargs环境变量的值

  

posted on 2019-12-19 15:50  lzd626  阅读(795)  评论(0编辑  收藏  举报