DTS即Device Tree Source 设备树源码, 是一种描述硬件的数据结构
DTS的加载过程
- 用户根据解自己的硬件配置和系统运行参数,编写DTS文件
- DTC(Device Tree Compiler)将DTS文件变成适合机器处理的DTB文件(Device Tree binary )
- 系统启动时,通过bootloader的交互式命令加载DTB到内核
Device Tree描述的信息
- CPU的数量和类别
- 内存基地址和大小
- 总线和桥
- 外设连接
- 中断控制器和中断使用情况
- GPIO控制器和GPIO使用情况
- Clock控制器和Clock使用情况
Device Tree的结构
由一系列被命名的结点(node)和属性(property)组成,
/ -------------根节点
@------------如果设备有地址,则由此符号指定
& -------------引用节点
:---------------冒号前的label是为了方便引用给节点起的别名,此label一般使用为&label
, -------------- 属性名称中可以包含逗号。如compatible属性的名字 组成方式为"[manufacturer], [model]",加入厂商名是为了避免重名。自定义属性名中通常也要有厂商名,并以逗号分隔。
#-------------并不表示注释。如 #address-cells ,#size-cells 用来决定reg属性的格式。
-----------空属性并不一定表示没有赋值。如 interrupt-controller 一个空属性用来声明这个node接收中断信号
“” --------------引号中的为字符串,字符串数组:”strint1”,”string2”,”string3”
< > ------------尖括号中的为32位整形数字,整形数组<12 3 4>
[ ] --------------方括号中的为32位十六进制数,十六机制数据[0x11 0x12 0x13] 其中0x可省略
结点本身可包含子结点。
/ { //根节点
node1 { //子结点
a-string-property = "A string";
a-string-list-property = "first string", "second string";
a-byte-data-property = [0x01 0x23 0x34 0x56];
child-node1 { //子节点的子节点
first-child-property;
second-child-property = <1>;
a-string-property = "Hello, world";
};
child-node2 {
};
};
node2 { //子节点
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
child-node1 {
};
};
};
#address-cells = <1>;
#size-cells = <1>;
external-bus {
#address-cells = <2>
#size-cells = <1>;
ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet
1 0 0x10160000 0x10000 // Chipselect 2, i2c controller
2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flash
ethernet@0,0 {
compatible = "smc,smc91c111";
reg = <0 0 0x1000>;
interrupts = < 5 2 >;
};
i2c@1,0 {
compatible = "acme,a1234-i2c-bus";
#address-cells = <1>;
#size-cells = <0>;
reg = <1 0 0x1000>;
rtc@58 {
compatible = "maxim,ds1338";
reg = <58>;
interrupts = < 7 3 >;
};
};
flash@2,0 {
compatible = "samsung,k8f1315ebm", "cfi-flash";
reg = <2 0 0x4000000>;
};
};
};
属性,其实就是成对出现的name和value
compatible属性
- 组织形式----------"<manufacturer>,<model>",manufacturer表征了结点代表的确切设备,特指。model表征可兼容的其他设备,泛指。
- 作用-----------用户驱动和设备的绑定
name属性
- 组织形式----------<name>[@<unit-address>],name指结点对应的设备类型,@unit-address表示结点设备的地址
- 作用-----------标识设备,多个相同类型设备结点的name可以一样,只要unit-address不同即可
reg属性
- 组织形式---------reg = <address1 length1 [address2 length2][address3 length3] ... >,
- 作用----------表明了设备使用的一个地址范围。父结点#address-cells和#size-cells分别决定了子结点reg属性的address和length字段的长度,子节点有特殊需求的话,可以自己再定义,这样就可以摆脱父节点的控制。
- address-cells=2----------一个是片选序号,另一个是片选序号上的偏移量,表示挂载在外部总线上,需要通过片选线工作的一些模块。
ranges属性
- 组织形式---------片选0,偏移0,被映射到CPU地址空间的0x10100000~0x10110000中,地址长度为0x10000(第一行)。
- 作用---------地址转换表,其中的每个项目是一个子地址、父地址以及在子地址空间的大小的映射。由子节点的address-cells的值、父节点的address-cells的值和子节点的size-cells来决定。
描述中断连接需要四个属性:
intc: interrupt-controller@10140000 {
compatible = "arm,pl190";
reg = <0x10140000 0x1000 >;
interrupt-controller;
#interrupt-cells = <2>;
};
1. interrupt-controller 一个空属性用来声明这个node接收中断信号;
2. #interrupt-cells 这是中断控制器节点的属性,用来标识这个控制器需要几个单位做中断描述符;
3. interrupt-parent 标识此设备节点属于哪一个中断控制器,如果没有设置这个属性,会自动依附父节点的;
4. interrupts 一个中断标识符列表,表示每一个中断输出信号。
二个cell的情况
spi@10115000 {
compatible = "arm,pl022";
reg = <0x10115000 0x1000 >;
interrupts = < 4 0 >;
};
第一个值: 该中断位于他的中断控制器的索引;
第二个值:触发的type
固定的取值如下:
1 (0001)= low-to-high edge triggered
2 (0010)= high-to-low edge triggered
4 (0100)= active high level-sensitive
8 (1000)= active low level-sensitive
三个cell的情况
第一个值:中断号
第二个值:触发的类型
第三个值:优先级,0级是最高的,7级是最低的;其中0级的中断系统当做 FIQ处理。
DTS设备树描述文件中什么代表总线,什么代表设备
一个含有compatible属性的节点就是一个设备。包含一组设备节点的父节点即为总线。