设备树简介

设备树简介

一:设备树由来
linux内核源码中,之前充斥着大量的平台相关(platform Device)配置,而这些代码大多是杂乱且重复的,这使得ARM体系结构的代码维护者和内核维护者在发布一个新的版本的时候有大量的工作要做,以至于Linus Torvalds 在2011年3月17日的ARM Linux邮件列表中宣称“Gaah.Guys,this whole ARM thing is a f*cking pain in the ass”这使得整个ARM社区不得不重新慎重考虑平台配置,于是设备树(Device Tree,DT)被ARM社区采用。需要说明的是,设备树最初是由开发固件(Open Firmware)使用的用来向客户程序(通常是一个操作系统)传递数据的通信方法中的一部分内容。在运行时,客户程序通过设备树发现设备的拓扑结构,这样就不需要把硬件信息硬编码到程序中。
二:设备树的作用
设备树是一个描述硬件的数据结构,甚至你可以将其看成一个大结构体(这个结构体就是平台,成员就是具体的设备),需要注意的是设备树并不能解决所有的硬件配置问题(例如:机器识别),它只是提供一种语言,将硬件的配置从linux内核的源码中提取出来。
Linux使用设备树的主要原因如下
A:平台识别
B:实时配置
C:设备植入
三:设备树的使用
在linux中,设备树文件的类型有.dts .dtsig和.dtb。其中,.dtsi是被包含的设备树源文件,类似于C语言中的头文件,.dts是设备数源文件,可以包含其他.dtsi文件,由dtc编译生成dtb文件。
设备树是一个包含节点和属性的简单树状结构。属性就是键值对,而节点可以包含属性和子节点。如下:

i2c2 {
	status = "okay";
	pinctrl-names="default";
	pinctrl-0=<&i2c2_z_pins>;
	clock-frequency = <400000>;
	tas5805: tas5805@36 {
		compatible = "ti,tas5805";
		#sound-dai-cells = <0>;
		codec_name = "tas5805";
		reg = <0x2d>;
		status = "disable";
	};
	ad82584f: ad82584f@62 {
		compatible = "ESMT, ad82584f";
		#sound-dai-cells = <0>;
		reg = <0x31>;
		status = "okay";
		//reset_pin = <&gpio_ao GPIOAO_6 0>;
	};
};

基本语法
1,属性就是简单的键值对,它的值可以为空或者包含一个任意字节流。在设备数源文件中有如下几种基本的数据表达形式
a,文本字符串(无结束符),可以用双引号表示,如 status = “okay”;
b,cells:32位无符号整数,用角括号限定,如 reg = <0x31>;
c,二进制数据:用方括号限定,如 a-byte-data-property=[0x01 0x23 0x34]
d,混合表示:使用逗号连接 如 Mixed-property=“a string”,<0x123>,[0x01 0x23]
e,字符串列表:使用逗号连接 如 string-list= “rea fish”,“bule fish”
2,包含其他的“.dtsi”文件 如 #include “skeletion.dtsi” 一个.dts(device tree source)文件对应一个ARM的machine,一般放置在内核的"arch/arm/boot/dts/“目录内,比如exynos4412参考板的板级设备树文件就是"arch/arm/boot/dts/exynos4412-origen.dts”。这个文件可以通过$make dtbs命令编译成二进制的.dtb文件供内核驱动使用。基于同样的软件分层设计的思想,由于一个SoC可能对应多个machine,如果每个machine的设备树都写成一个完全独立的.dts文件,那么势必相当一些.dts文件有重复的部分,为了解决这个问题,Linux设备树目录把一个SoC公用的部分或者多个machine共同的部分提炼为相应的.dtsi文件。这样每个.dts就只有自己差异的部分,公有的部分只需要"include"相应的.dtsi文件, 这样就是整个设备树的管理更加有序。
3,节点名称,是一个“<名称>[@<设备地址>]”,其中方括号中的内容可以省略。“名称“是一个不超过31位的ASCII字符串,应该根据它所体现的设备来进行命名。如果该节点描述的设备有地址存在,就应该加上单元地址,通常设备地址就是访问该设备的主地址,并且该地址会在节点的reg属性中列出。同级节点命名必须是唯一的,但只要地址不同,多个节点也可以使用一样的通用名称,如 serial@13800000与serial@13810000
4,compatible属性,系统中每一个设备都表示一个节点,每个设备树节点都有一个compatible属性。该属性是操作系统用来决定使用哪个设备驱动来绑定到一个设备上的关键因素。compatible是一个字符串列表,格式:"<制造商>,<型号>"
5,可编码设备使用如下属性将地址信息编码进设备树:reg、#address-cells、#size-cells。每个可编址设备都有一个reg,它是一个元素表,形式为:reg=<地址1 长度1 [地址2 长度2] [地址3 长度3]…>,每个元祖都表示改设备使用的一个地址范围。每个地址值是一个或者多个32整数列表,成为cell。同样长度值也是一个cell列表。由于地址和长度字段都是可变大小的变量,那么父节点的#adderss-cells和#size-cells属性就用来声明各个字段的cell数量。换句话说,正确完整的解释reg属性需要用到父节点的#address-cells和#size-cells的值。如下:

i2c@13860000 {
	#address-cells = <1>;
	#size_cells = <0>;
	s5m8767_pmic@0x66 {
		compatible = "samsung, s5m8767_pmic";
		reg = <0x66>;
	}
};

其中,I2C主机控制器是一个父节点,地址的长度为一个32位整形数,地址长度为0,s5m8767_pmic是I2C主机控制器下面的一个子节点,起地址为0x66.
6,描述中断连接需要如下四个属性
A,interrupt-controller:一个空的属性,用来定义改节点是一个接收中断的设备,即是一个中断控制器
B,interrupt-cells:一个中断控制器节点的属性,声明了该中断控制器的终端指示符中cell的个数,类似于#address-cells
C,interrupt-parent:一个设备的节点的属性,指向设备所连接的中断控制器。如果这个设备节点没有该属性,那么这个节点继承父节点的这个属性
D,interrupt:一个设备节点的属性,含一个中断指示符的列表,对应于改设备上的每个中断输出信号。
值得注意的是ARM公司开发的是GIC中断控制器,其有三个参数(三个cell),第一个是中断类型、第二个是中断号,第三个是中断触发类型。
7,aliases节点用于指定节点的别名。因为引用一个节点要使用全路径,当子节点离根节点较远时,节点名就会显得比较冗长,定义一个别名则比较方便。如下,将spi_0定义为spi0

aliases {
	spi0 = &spi_0;
};

8,chosen节点并不代表一个真正的设备,只是一个为固件和操作系统传递数据的地方,如引导参数。chosen节点里面的数据也不代表硬件。
9,设备特定数据,用于定义特定于某个具体设备的一些属性。这些属性可以自由定义,但是新的设备特定属性的名字都应该使用制造商前缀,以避免和现有标准属性名相冲突。

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值