1:设备树:描述板级硬件信息的内容都从 Linux 内中分离开来,用一个专属的文件格式来描述,这个专属的文件就叫做设备树,文件扩展名为.dts;dtsi 描述 SOC 级信息(也就是 SOC 有几个 CPU、主频是多少、各个外设控制器信息等),一般.dts 描述板级信息(也就是开发板上有哪些 IIC 设备、SPI 设备等)
dts:设备树源文件
dtd:设备树编译后得二进制文件
dtc:编译设备树的工具
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-
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环境变量的值