linux设备树的学习

设备树的学习



什么是设备树

设备树(Device Tree),将这个词分开就是“设备”和“树”,描述设备树的文件叫做 DTS(Device
Tree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比如
CPU 数量、 内存基地址、 IIC 接口上接了哪些设备、 SPI 接口上接了哪些设备等等,如图所示
在这里插入图片描述
在图中,树的主干就是系统总线, IIC 控制器、 GPIO 控制器、 SPI 控制器等都是接到系统主线上的分支。IIC 控制器有分为 IIC1 和 IIC2 两种,其中 IIC1 上接了 FT5206 和 AT24C02这两个 IIC 设备, IIC2 上只接了 MPU6050 这个设备。 DTS 文件的主要功能就是按照上图所示的结构来描述板子上的设备信息,


提示:以下是本篇文章正文内容,下面案例可供参考

一、设备节点

设备树是采用树形结构来描述板子上的设备信息的文件,每个设备都是一个节点,叫做设备节点,每个节点都通过一些属性信息来描述节点信息,属性就是键—值对。以下是从imx6ull.dtsi 文件中缩减出来的设备树文件内容:
在这里插入图片描述
其中第 1 行,“/”是根节点,每个设备树文件只有一个根节点。
第 2、 6 和 17 行, aliases、 cpus 和 intc 是三个子节点
第 10 行, cpu0 也是一个节点,只是 cpu0 是 cpus 的子节点。 每个节点都有不同属性,不同的属性又有不同的内容,属性都是键值对,值可以为空或任意的字节流

二、DTS启动内核的过程

接下来我们简单看一下 Linux 内核是如何根据设备树根节点的 compatible 属性来匹配出对应的 machine_desc, Linux 内核调用 start_kernel 函数来启动内核, start_kernel 函数会调用setup_arch 函数来匹配 machine_desc,找到匹配的 machine_desc 的过程就是用设备树根节点的compatible 属性值和 Linux 内核中 machine_desc 下.dt_compat 的值比较,看看那个相等,如果相等的话就表示找到匹配的 machine_desc。第 715~720 行,此循环就是查找匹配的 machine_desc 过程,第 716 行的 of_flat_dt_match 函数会将根节点 compatible 属性的值和每个 machine_desc 结构体中. dt_compat 的值进行比较,直至找到匹配的那个 machine_desc。
在这里插入图片描述
Linux 内核通过根节点 compatible 属性找到对应的设备的函数调用过程如下图所示
在这里插入图片描述
machine_desc 结构体中有个.dt_compat 成员变量,此成员变量保存着本设备兼容属性,当设备树中的compatible 属性值和linux内核中的_dt_compat 表里面的值有相等时,那么就表示 Linux 内核支持此设备。

三.创建一个小型模板设备树

在实际产品开发中,我们是不需要完完全全的重写一个.dts 设备树文件,一般都是使用 SOC 厂商提供好的.dts 文件,我们只需要在上面根据自己的实际情况做相应的修
改即可。在编写设备树之前要先定义一个设备,我们就以 I.MX6ULL 这个 SOC 例,我们需要在设备树里面描述的内容如下:
在这里插入图片描述

//设备树基础框架
/ {
    
    
	compatible = "fsl,imx6ull-alientek-evk", "fsl, imx6ull";
	
	cpus {
    
    
		#address-cells = <1>;
		#size-cells = <0>;
		
		//CPU0节点
		cpu0: cpu@0 {
    
    
			compatible = "arm, cortex-a7";
			device_type = "cpu";
			reg = <0>;
		};
	};
	
	//soc节点
	soc {
    
    
		#address-cells = <1>;
		#size-cells = <1>;
		
		compatible = "simple-bus";
		ranges;					//ranges 属性为空,说明子空间和父空间地址范围相同
		
		//ocram节点
		ocram: sram@00900000 {
    
    
			compatible = "fsl,lpm-sram";
			reg = <0x00900000 0x20000>;
		};
		
		//aips1节点
		aips1: aips-bus@02000000 {
    
    
			compatible = "fsl,aips-bus", "simple-bus";
			#address-cells = <1>;
			#size-cells = <1>;
			reg = <0x02000000 0x100000>;
			ranges;
			
			//ecspi1节点
			ecspi1: ecspi@02008000 {
    
    
				#address-cells = <1>;
				#size-cells = <0>;
				compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
				reg = <0x02008000 0x4000>;
				status = "disabled";
			};
		}
		
		//aips2节点
		aips2: aips-bus@02100000 {
    
    
			compatible = "fsl,aips-bus", "simple-bus";
			#address-cells = <1>;
			#size-cells = <1>;
			reg = <0x02100000 0x100000>;
			ranges;
			
			//usbotg1: usb@02184000 {
    
    
				compatible = "fsl,imx6ul-usb", "fsl,imx27-usb";
				reg = <0x02184000 0x4000>;
				status = "disabled";
			};
		}
		
		//aips3节点
		aips3: aips-bus@02200000 {
    
    
			compatible = "fsl,aips-bus", "simple-bus";
			#address-cells = <1>;
			#size-cells = <1>;
			reg = <0x02200000 0x100000>;
			ranges;
			
			//rngb节点
			rngb: rngb@02284000 {
    
    
				compatible =  "fsl,imx6sl-rng", "fsl,imx-rng", "imxrng";
				reg = <0x02284000 0x4000>;
			};
		}
		
	}
}


四、设备树在系统中的体现

Linux 内核启动的时候会解析设备树中各个节点的信息,并且在根文件系统的/proc/devicetree 目录下根据节点名字创建不同文件夹,如图所示
在这里插入图片描述
上图就是目录/proc/device-tree 目录下的内容, /proc/device-tree 目录下是根节点“/”的所有属性和子节点

猜你喜欢

转载自blog.csdn.net/m0_57730390/article/details/127430720