• 技术文章 >运维 >linux运维

    linux dts有什么用

    青灯夜游青灯夜游2023-03-14 10:44:27原创105

    在linux中,dts是设备树源文件,用于描述设备信息的;设备树技术将设备的硬件资源信息就写在dts文件中。设备树源文件dts被编译成dtb二进制,在bootloader运行时传递给操作系统,操作系统对其进行解析展开,从而产生一个硬件设备的拓扑图,有了这个拓扑图,在编成过程可以直接通过系统提供的接口获取到设备树的节点和属性信息。

    本教程操作环境:linux7.3系统、Dell G3电脑。

    1、什么是设备树?

    设备树(dt:device tree)是linux内核采用的参数表示和传递技术,在系统引导启动阶段进行设备初始化的时候,将设备树中描述的硬件信息传递给操作系统;

    2、设备树解决什么问题

    3、设备树怎么工作

    1.png

    4、设备树源码dts文件格式讲解

    4.1、dts文件在内核源码中的存放位置

    arm架构:arch/arm/boot/dts目录中

    4.2、dts文件格式简介

    4.3、节点格式

    4.3.1、格式定义

    [label:] <node-name> [@<unit-address>]{
      [property]
      [child nodes]
      [child nodes]
      ......
    };

    4.3.2、格式解读

    4.3.3、示例代码

    cpus {
    	/* 下面三项是cpus节点的属性 */
    	#address-cells = <1>;
    	#size-cells = <0>;
    	enable-method = "hisilicon,hi3516dv300";
    
    	/* 下面是子节点 */
    	cpu@0 {
    		device_type = "cpu";
    		compatible = "arm,cortex-a7";
    		clock-frequency = <HI3516DV300_FIXED_1000M>;
    		reg = <0>;
    	};
    };

    5、节点属性分析

    5.1、GPIO属性格式

    /{
    	gpx1:gpx1{
    		controller;
    		#gpio-cells=<2>;
    	};
    	
    	key@11400c24{
    		compatible="fs4412,key";
    		reg=<0x11400c24 0x4>;
    		intn-key=<&gpx1 2 2>;
    	}
    }

    5.2、compatible属性格式

    uart0: uart@120a0000 {
    	compatible = "arm,pl011", "arm,primecell";
    	reg = <0x120a0000 0x1000>;
    	interrupts = <0 6 4>;
    	clocks = <&clock HI3516DV300_UART0_CLK>;
    	clock-names = "apb_pclk";
    	status = "disabled";
    };
    
    /* 在驱动中对应的结构体*/
    
    //struct device_driver->of_match_table->compatible
    
    struct of_device_id {
    	char	name[32];
    	char	type[32];
    	char	compatible[128];
    	const void *data;
    };

    (1)compatible属性是用于设备节点和设备驱动匹配用的,在内核描述驱动的structdevice_driver结构体中,compatible变量中就会保存用于匹配的字符串,当设备节点和驱动的

    compatible相同时就匹配成功;

    (2)compatible后面可以有多个字符串,优先匹配靠前的字符串,靠前的字符串匹配不上才会匹配后面的字符串;

    5.3、model属性格式

    / {
    	model = "Tyr DEMO Board";
    	compatible = "hisilicon,hi3516dv300";
    
    	memory {
    		device_type = "memory";
    		reg = <0x82000000 0x20000000>;
    	};};

    (1)model是描述模块信息的,一般只有根节点才有,标明设备树文件对应的开发板的名称;

    (2)在内核的启动打印中可以看到model的值:“OF: fdt:Machine model: Tyr DEMO Board”;

    5.4、status属性格式

    &uart0 {
    	status = "okay";
    };
    状态值含义
    okey表示设备是可操作的
    disabled表示当前不可操作,但是后续是可以更改为可操作性的
    fail、failed表示有严重错误,几乎不可能再可操作了

    (1)status描述设备信息状态,在设备树文件中可以根据需求设置模块的状态,功能就是开启/关闭某个模块;

    (2)在dtsi文件中,默认都是关闭模块的,在开发板对应的dts文件中自己去打开需要的模块;

    5.5、reg属性格式

    clock: clock@12010000 {
    	compatible = "hisilicon,hi3516dv300-clock";
    	#address-cells = <1>;	/* 表示reg里面的数据address占用一个字长*/
    	#size-cells = <1>;		/* 表示reg里面的数据size占用一个字长,注意字长不是字节*/
    	#clock-cells = <1>;
    	#reset-cells = <2>;
    	reg = <0x12010000 0x1000>;	/*起始地址是0x12010000,长度是0x1000*/
    };

    5.6、中断属性格式

    gic: interrupt-controller@10300000 {
    	compatible = "arm,cortex-a7-gic";
    	#interrupt-cells = <3>;	/*表示interrupts用三个cell来描述中断*/
    	#address-cells = <0>;
    	interrupt-controller;	/*标明gic节点是中断控制器*/
    	/* gic dist base, gic cpu base , no virtual support */
    	reg = <0x10301000 0x1000>, <0x10302000 0x100>;
     };
    	
    ipcm: ipcm@045E0000 {
    	compatible = "hisilicon,ipcm-interrupt";
    	interrupt-parent = <&gic>;	/*父节点是gic节点*/
    	interrupts = <0 10 4>;	/*<中断域 中断 触发方式>*/
    	reg = <0x10300000 0x4000>;	
    	status = "okay";
    };

    (1)interrupt-controller:无值属性,表示这是个中断控制器node
    (2)#interrupt-cells:这是中断控制器节点的属性,用来标识这个控制器需要几个cell做中断描述符
    (3)interrupt-parent:标识此设备节点属于哪一个中断控制器,如果没有这个属性,会自动依附父节点
    (4)interrupts :一个中断标识符列表,表示每一个中断输出信号

    6、特殊节点

    6.1、chosen子节点

    6.1.1、chosen子节点功能介绍

    chosen {
    	stdout-path = "serial0:115200n8";
    };

    (1)chosen子节点不对应真实的设备,是用来描述内核启动参数的,对应于uboot启动内核时传递的bootargs参数;
    (2)上面是摘抄的内核dts文件中的chosen子节点,里面只设置了stdout-path属性,也就是把输出设置成串口0,波特率是115200;
    (3)dts文件中设置的属性会被覆盖点,具体就是uboot在启动内核时,会将bootargs启动参数转换成chosen子节点的属性,替换掉dts文件中设置的属性;

    6.1.2、chosen子节点在内核中的体现

    ~ # ls /proc/device-tree/chosen/
    bootargs  name
    ~ # 
    ~ # cat /proc/device-tree/chosen/bootargs 
    mem=1408M console=ttyS0,115200 root=/dev/mmcblk0p7 rootfstype=squashfs rootwait
    ~ # 
    ~ # cat /proc/device-tree/chosen/name 
    chosen
    ~ #

    6.2、aliases子节点

    	aliases {
    		serial0 = &uart0;
    		gpio0 = &gpio_chip0;
    		gpio1 = &gpio_chip1;
    		gpio2 = &gpio_chip2;
    		······	
    	};

    aliases就是别名的意思,aliases节点主要功能就是给节点定义别名,为了方便访问节点。不过我们在节点命名的时候可以加上label标签,直接通过&label引用标签来访问也很方便,aliases节点内部其实也是通过引用标签名来定义别名;

    7、节点相关操作

    7.1、节点引用和内容替换

    gpio_chip1: gpio_chip@120d1000 {
    	compatible = "arm,pl061", "arm,primecell";
    	reg = <0x120d1000 0x1000>;
    	interrupts = <0 17 4>;
    	clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
    	clock-names = "apb_pclk";
    	#gpio-cells = <2>;
    	status = "disabled";
    };
    
    /*引用gpio_chip1节点*/
    &gpio_chip1 {
    	status = "okay";	/*替换status属性内容*/
    };

    对于已经定义好的节点,我们通过引用节点的方式,重新定义某些属性,效果上看就是替换掉某些属性的值;

    7.2、合并节点内容

    /{
    	node{
    		key1=value1;
    	}
    }
    
    /{
    	node{
    		key2=value2;
    	}
    }
    
    //合并的结果
    /{
    	node{
    		key1=value1;
    		key2=value2;
    	}
    }

    有时候我们需要增加硬件描述的信息,这时候就可以在后面创新定义该节点,最后解析的时候会把同名节点不同的部分进行合并;

    相关推荐:《Linux视频教程

    以上就是linux dts有什么用的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:linux
    上一篇:linux linkwatch是什么进程 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • linux 删除分区对数据有什么影响• php linux文件路径是否存在怎么判断• linux mysql启动用什么权限• linux mbr grub是什么• linux localhost是什么意思• linux i386是几位• linux ftp 530什么意思
    1/1

    PHP中文网