活动地址:CSDN21天学习挑战赛
原文专栏地址:RK3399平台开发入门到精通系列专栏
原文地址:RK3399平台开发系列讲解(内核设备树篇)3.2、图解Kernel Device Tree(设备树)的使用
以前也接触过 Linux 的内核,主要就是编写一些小的驱动,调试一些模块,但没有真正地去研究过内核底层,因为底层已经由芯片厂商整理好,无需我去调试。现在趁着这个 21 天学习挑战赛,我打算认真学习一下 Linux 内核的一些基本知识,说不定以后能用上。
设备树 Device Tree 可以描述的硬件信息包括:
下面是一个 Device Tree 的示例(来自课程原文),重要的属性包括 compatible、reg、clocks、interrupts 和 status。这些属性的具体介绍写在后面的章节。下图摘自原文。

设备树的结构很简单,主要由 Node(节点)和 Property(属性)组成。比如上图就是一个 Node,系统中每个设备都用一个 Node 来描述,这些 Node 被组织成树状结构。每个 Node 中包含了若干的 Property/Value 来描述 Node 的一些特性。
每个 Node 用 node name 进行标识,节点名字由 node-name 和 unit-address 组成。node-name 说明了设备的名字,必须使用字符开头,unit-address 为此设备的主地址,要求唯一且与此节点的 reg 属性的开始地址一致。
设备树格式示例:
[label:] node-name[@unit-address] {
[properties definitions]
[child nodes]
}
“[ ]” 表示可选项,label 是 Node 的标识,便于在 dts 文件中引用。 child node 的格式和 node 完全相同。
一个设备树只能有一个根节点(root node),至少需要由 cpu 和 memory 节点组成。
例如(原文的示例)
/ {
compatible = "rockchip,rk3399";
interrupt-parent = <&gic>;
#address-cells = <2>;
#size-cells = <2>;
cpus {
......
}
aliases 节点可以用来定义别名节点。在引用一个节点时需要指定其完整地址,如果每次引用都要写完整的地址,未免有些麻烦,而 aliases 可以解决这个问题。下图摘自原文。

前面提到,根节点必须有一个 cpu 节点,下面的例子摘自原文:
cpus {
#address-cells = <2>;
#size-cells = <0>;
cpu_l0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0x0 0x0>;
enable-method = "psci";
#cooling-cells = <2>; /* min followed by max */
clocks = <&cru ARMCLKL>;
dynamic-power-coefficient = <100>;
};
memory device node 是所有设备树文件的必备节点,它描述了系统的物理内存布局。
chosen 主要用来描述由系统硬件指定的运行参数,并不是一个真实的设备,该节点主要是为了 uboot 向 Linux 内核传递数据。重点是 bootargs 这个参数,例如:
chosen { bootargs = "console=ttymxc0,115200"; };
compatible 属性通常用来实现 device 和 driver 的适配,推荐格式为 “manufacturer,model”
驱动文件中一般都有一个 OF 匹配表,里面有一些 compatible 值,如果设备节点的 compatible 与驱动 OF 匹配表中任何一个相同,那么表示该设备可以使用这个驱动。
model 属性用来表示型号,一般用来描述设备模块的信息,如名字。
如果设备节点中有寻址需求(定义了 reg),那就必须要定义下面这两个属性:
‘#’ 符号表示 number 的意思,#address-cells 用来描述 sub node 中 reg 属性的地址域特性,即要用多少个 u32 来描述地址域。如:
reg = <address1 length1 [address2 length2] [address3 length3] ... >
#size-cells 用来表示地址长度。
下图摘自原文:

中断属性包括 interrupt-controller,#interrupt-celles,interrupt-parent 和 interrupts。
暂时先不学习。
设备树中一般使用 okay 和 disabled 来打开或关闭设备,下面是一些与设备状态有关的值:
| 值 | 描述 |
|---|---|
| “okay” | 设备可操作(已开启) |
| “diable” | 设备不可操作(已关闭) |
| “fail” | 设备不可操作,设备检测到了一些错误 |
| “fail-sss” | 同 “fail” |