设备树的规范(dts)
设备树的官方文档:
https://www.devicetree.org/specifications/
一、理论部分
如何看下面这张图:
1)从根节点开始看起,即 /
2)在根节点中有属性以及设备节点名称
3)属性的格式有两种形式:property-name = value;property-name ;(一个有值,一个没值)
当property-name = value时,value的取值有三种形式
4)设备节点(child nodes)的格式

总结:
(1) 语法:
Devicetree node格式:
[label:] node-name[@unit-address] {
[properties definitions]
[child nodes]
};
Property格式1:
[label:] property-name = value;
Property格式2(没有值):
[label:] property-name;
Property取值只有3种:
arrays of cells (1个或多个32位数据, 64位数据使用2个32位数据表示),
string (字符串),
bytestring (1个或多个字节)
示例:
a. Arrays of cells : cell就是一个32位的数据
interrupts = <17 0xc>;
b. 64bit数据使用2个cell来表示:
clock-frequency = <0x00000001 0x00000000>;
c. A null-terminated string (有结束符的字符串):
compatible = "simple-bus";
d. A bytestring(字节序列) :
local-mac-address = [00 00 12 34 56 78]; // 每个byte使用2个16进制数来表示
local-mac-address = [000012345678]; // 每个byte使用2个16进制数来表示
e. 可以是各种值的组合, 用逗号隔开:
compatible = "ns16550", "ns8250";
example = <0xf00f0000 19>, "a strange property format";
(2) DTS文件布局(layout):
/dts-v1/;
[memory reservations] // 格式为: /memreserve/ <address> <length>;
/ {
[property definitions]
[child nodes]
};
(3) 特殊的、默认的属性:
a. 根节点:
#address-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)
例子:
#address-cells = <1>;
#size-cells = <1>;
memory@30000000 {
device_type = "memory";
reg = <0x30000000 0x4000000>;
};
在子节点的reg属性中,0x30000000表示地址,0x4000000来表示大小。我凭什么知道在reg中用一个32位整数来描述地址,一个32位整数来描述大小。就是通过
#address-cells = <1>;
#size-cells = <1>;
进行指定的。
compatible // 定义一系列的字符串, 用来指定内核中哪个machine_desc可以支持本设备
// 即这个板子兼容哪些平台
// uImage : smdk2410 smdk2440 mini2440 ==> machine_desc 。一个uImage可以支持多种单板,比如说 smdk2410、smdk2440、mini2440。每种单板在内核中都有一个对应的machine_desc结构体,里面会有不同的初始化函数。因此利用compatible这个属性可以选择单板,让内核去执行对应的初始化函数。
举例:
compatible = "samsung,smdk2440"; 通过这样指定,内核就会去执行smdk2440中的初始化函数
compatible可以是一个或多个字符串。比如说compatible = "samsung,smdk2440" "samsung,smdk24xx"
smdk2440就更加具体,s3c24xx就比较广泛些,可以适配更多的单板。使用设备树时,优先去内核中寻找支持smdk2440的machine_desc,如果找不到的话,再去寻找支持smdk24xx的machine_desc。优先选择第一项,如果没有,再往后选择。
model // 咱这个板子是什么
// 比如有2款板子配置基本一致, 它们的compatible是一样的
// 那么就通过model来分辨这2款板子
b. /memory
device_type = "memory"; //这是约定俗称的,必须写这个。
reg // 用来指定内存的地址、大小
c. /chosen
bootargs // 内核command line参数, 跟u-boot中设置的bootargs作用一样
例子:
chosen {
bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200"; //内核启动时的命令行参数
};
d. /cpus
/cpus节点下有1个或多个cpu子节点, cpu子节点中用reg属性来标明自己是哪一个cpu
既然谈到了reg属性,那么必定少不了两个东西:#address-cells和#size-cells
所以 /cpus 中有以下2个属性:
#address-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)
// 必须设置为0
e. /cpus/cpu*
device_type = "cpu"; //在cpus/cpu这个子节点中,必须有一个device_type = "cpu"
reg // 表明自己是哪一个cpu
(4) 引用其他节点:
a. phandle : // 节点中的phandle属性, 它的取值必须是唯一的(不要跟其他的phandle值一样)
pic@10000000 {
phandle = <1>;
interrupt-controller; //表明pic@10000000是一个中断控制器,
};
another-device-node { //这个设备产生了中断,要传给中断控制器,就需要在能发出中断的这个节点another-device-node中,指定 //它的interrupt-parent。那么在这个地方如何引用中断控制器呢?有两种方法:可以在中断控制器里面使用 //phandle=某个值,这个值是唯一的。比如说有其他的节点里面phandle= <1>,那么此处的phandle就不 //能 等于1。
interrupt-parent = <1>; // 使用phandle值为1来引用上述节点,这种方法有点麻烦。
};
b. label: //第二种方法
PIC: pic@10000000 { //该节点为一个中断控制器。如果在其他节点中要引用此节点的话,可以使用它的lable。
interrupt-controller;
};
another-device-node {
interrupt-parent = <&PIC>; // 使用label来引用上述节点,
// 使用lable时实际上也是使用phandle来引用,
// 在编译dts文件为dtb文件时, 编译器dtc会在dtb中插入phandle属性
};
注意第二种方法的实现方式其实和第一种是相同的,编译dts文件时,编译器会在中断控制器所在的节点中加入一个phandle= <xxxx>。将interrupt-parent = <&PIC>替换为interrupt-parent = <xxxx>;这都是编译器帮我们做的。
二、代码
设备树文件里面,它把一些公共的部分写为dtsi文件,dts文件可以去包含dtsi文件,两者的语法格式是一样的。
1、override问题
jz2440.dtsi
// SPDX-License-Identifier: GPL-2.0
/*
* SAMSUNG SMDK2440 board device tree source
*
* Copyright (c) 2018 weidongshan@qq.com
* dtc -I dtb -O dts -o jz2440.dts jz2440.dtb
*/
#define S3C2410_GPA(_nr) ((0<<16) + (_nr))
#define S3C2410_GPB(_nr) ((1<<16) + (_nr))
#define S3C2410_GPC(_nr) ((2<<16) + (_nr))
#define S3C2410_GPD(_nr) ((3<<16) + (_nr))
#define S3C2410_GPE(_nr) ((4<<16) + (_nr))
#define S3C2410_GPF(_nr) ((5<<16) + (_nr))
#define S3C2410_GPG(_nr) ((6<<16) + (_nr))
#define S3C2410_GPH(_nr) ((7<<16) + (_nr))
#define S3C2410_GPJ(_nr) ((8<<16) + (_nr))
#define S3C2410_GPK(_nr) ((9<<16) + (_nr))
#define S3C2410_GPL(_nr) ((10<<16) + (_nr))
#define S3C2410_GPM(_nr) ((11<<16) + (_nr))
/dts-v1/;
/ {
model = "SMDK24440";
compatible = "samsung,smdk2440";
#address-cells = <>;
#size-cells = <>;
memory { /* /memory */
device_type = "memory";
reg = < >;
};
/*
cpus {
cpu {
compatible = "arm,arm926ej-s";
};
};
*/
chosen {
bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";
};
led {
compatible = "jz2440_led";
pin = <S3C2410_GPF()>;
};
};
本来led默认的pin = <S3C2410_GPF(5)>;但是我不想使用这个引脚,并且我也不想去修改这个dtsi文件。怎么办?
可以在jz2440_dts文件中将其覆盖。如下所示:
// SPDX-License-Identifier: GPL-2.0
/*
* SAMSUNG SMDK2440 board device tree source
*
* Copyright (c) 2018 weidongshan@qq.com
* dtc -I dtb -O dts -o jz2440.dts jz2440.dtb
*/
/dts-v1/;
#include "jz2440.dtsi"
/ {
led {
pin = <S3C2410_GPF()>;
};
};
2、lable问题
上面的这个例子中,在dts文件中引用在dtsi中定义的led节点,是非常麻烦的。
/ {
led {
};
}
此时lable就派上用场了。
// SPDX-License-Identifier: GPL-2.0
/*
* SAMSUNG SMDK2440 board device tree source
*
* Copyright (c) 2018 weidongshan@qq.com
* dtc -I dtb -O dts -o jz2440.dts jz2440.dtb
*/
#define S3C2410_GPA(_nr) ((0<<16) + (_nr))
#define S3C2410_GPB(_nr) ((1<<16) + (_nr))
#define S3C2410_GPC(_nr) ((2<<16) + (_nr))
#define S3C2410_GPD(_nr) ((3<<16) + (_nr))
#define S3C2410_GPE(_nr) ((4<<16) + (_nr))
#define S3C2410_GPF(_nr) ((5<<16) + (_nr))
#define S3C2410_GPG(_nr) ((6<<16) + (_nr))
#define S3C2410_GPH(_nr) ((7<<16) + (_nr))
#define S3C2410_GPJ(_nr) ((8<<16) + (_nr))
#define S3C2410_GPK(_nr) ((9<<16) + (_nr))
#define S3C2410_GPL(_nr) ((10<<16) + (_nr))
#define S3C2410_GPM(_nr) ((11<<16) + (_nr))
/dts-v1/;
/ {
model = "SMDK24440";
compatible = "samsung,smdk2440";
#address-cells = <>;
#size-cells = <>;
memory { /* /memory */
device_type = "memory";
reg = < >;
};
/*
cpus {
cpu {
compatible = "arm,arm926ej-s";
};
};
*/
chosen {
bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";
};
LED: led {
compatible = "jz2440_led";
pin = <S3C2410_GPF()>;
};
};
在dts文件中,
// SPDX-License-Identifier: GPL-2.0
/*
* SAMSUNG SMDK2440 board device tree source
*
* Copyright (c) 2018 weidongshan@qq.com
* dtc -I dtb -O dts -o jz2440.dts jz2440.dtb
*/
/dts-v1/;
#include "jz2440.dtsi"
&LED {
pin = <S3C2410_GPF()>;
};
设备树的规范(dts)的更多相关文章
- Linux 获取设备树源文件(DTS)里描述的资源
Linux 获取设备树源文件(DTS)里的资源 韩大卫@吉林师范大学 在linux使用platform_driver_register() 注册 platform_driver 时, 需要在 plat ...
- Linux 获取设备树源文件(DTS)里的资源【转】
本文转载自:http://blog.csdn.net/keleming1/article/details/51036000 http://www.cnblogs.com/dyllove98/archi ...
- Linux 获取设备树源文件(DTS)里描述的资源【转】
转自:http://www.linuxidc.com/Linux/2013-07/86839.htm 转自:http://blog.sina.com.cn/s/blog_636a55070101mce ...
- 2、设备树的规范(dts和dtb格式)
第01节_DTS格式(1) 语法:Devicetree node格式:[label:] node-name[@unit-address] { [properties definitions] ...
- rk3328设备树学习
一.用到的rk3328好像使用了设备树 设备树我知道的有三种文件类型,dtbs是通过指令make dtbs编译的二进制文件,供内核使用. 基于同样的软件分层设计的思想,由于一个SoC可能对应多个mac ...
- 设备树DTS 学习:2-设备树语法
背景 通过上一讲了解完设备树DTS有关概念,我们这一讲就来基于设备树例程,学习设备树的语法规则. 参考:设备树详解dts.设备树语法详解.设备树使用总结 设备树框架 1个dts文件 + n个dtsi文 ...
- linux设备树笔记__dts基本概念及语法【转】
转自:http://www.360doc.com/content/15/1113/11/15700426_512794532.shtml 设备树手册(Device Tree Usage)原文地址:ht ...
- 我眼中的Linux设备树(一 概述)
一 概述设备树(Device tree)是一套用来描述硬件属相的规则.ARM Linux采用设备树机制源于2011年3月份Linux创始人Linus Torvalds发的一封邮件,在这封邮件中他提倡A ...
- Linux设备树(一 概述)
一 概述 设备树(Device tree)是一套用来描述硬件属相的规则.ARM Linux采用设备树机制源于2011年3月份Linux创始人Linus Torvalds发的一封邮件,在这封邮件中他提倡 ...
随机推荐
- Spring Boot 2.2.1 正式发布,需特别注意这个注解的使用!
Spring Boot 2.2.1 已于2019年11月7日正式发布. 该版本内容包含110项修复.改进和依赖升级. 如果开发者要从Spring Boot 2.2.0升级到2.2.1的话,这里要特别注 ...
- 【转】struts2的ActionInvocation分析(action调度者)
一个ActionInvocation实例代表一个action的执行状态,持有拦截器和将要执行的action的实例. defaultActionInvocation是其默认实现.下面是定义在该类中的部分 ...
- [LOJ 6432][PKUSC 2018]真实排名
[LOJ 6432][PKUSC 2018]真实排名 题意 给定 \(n\) 个选手的成绩, 选中其中 \(k\) 个使他们的成绩翻倍. 对于每个选手回答有多少种方案使得他的排名不发生变化. \(n\ ...
- MySQL实战45讲学习笔记:第二十五讲
一.引子 在上一篇文章中,我和你介绍了 binlog 的基本内容,在一个主备关系中,每个备库接收主库的 binlog 并执行. 正常情况下,只要主库执行更新生成的所有 binlog,都可以传到备库并被 ...
- 第四组 团队Git现场编程实战
组员职责分工 组员 分工 林涛(组长) 分配任务.整理数据.写博客 童圣滔 UI界面制作 林红莲 UI界面制作 潘雨佳 测评出福州最受欢迎的商圈 于瀚翔 测评出福州最受欢迎的商圈 覃鸿浩 测评出福州人 ...
- Nginx+Tomcat+Memcache 实现session共享
Nginx + Tomcat + Memcache 实现session共享 1. Nginx 部署 1.上传源码包到服务器,解压安装 下载地址:http://nginx.org/en/download ...
- mysql id 自增实现
1.在mysql中建表 2.使用: >insert into 表名 values(id,'www',66); 连续运行5次后结果: =============================== ...
- TiDB 压力测试报告
(转载自公众号DBATech) 一.测试环境 1.tidb 集群架构: 测试使用最基本的TiDB架构.即 3个tidb-server节点+ 3个tikv节点 + 3个pd节点. 2.tidb集群的部署 ...
- Chrome教程之使用Chrome DevTools命令菜单运行命令
1.模拟移动设备 点击 Toggle Device Toolbar 2.限制网络流量和 CPU 占用率 要限制网络流量和 CPU 占用率,请从 Throttle 列表中选择 Mid-tier mobi ...
- Linux chattr 文件保护
Linux chattr 文件保护 chattr命令的用法:chattr [ -RV ] [ -v version ] [ mode ] files…注:最关键的是在[mode]部分,[mode]部分 ...