Was nützt Linux DTS?

青灯夜游
青灯夜游Original
2023-03-14 10:34:081531Durchsuche

Unter Linux ist dts eine Gerätebaum-Quelldatei, die zur Beschreibung von Geräteinformationen verwendet wird; die Gerätebaum-Technologie schreibt die Hardwareressourceninformationen des Geräts in die dts-Datei. Die Gerätebaum-Quelldatei dts wird in eine dtb-Binärdatei kompiliert und an das Betriebssystem übergeben, wenn der Bootloader ausgeführt wird. Das Betriebssystem analysiert und erweitert es, um ein Topologiediagramm des Hardwaregeräts zu erstellen direkt übergeben werden Die vom System bereitgestellte Schnittstelle ruft die Knoten- und Attributinformationen des Gerätebaums ab.

Was nützt Linux DTS?

Die Betriebsumgebung dieses Tutorials: Linux7.3-System, Dell G3-Computer.

1. Was ist ein Gerätebaum?

Gerätebaum (dt: Gerätebaum) ist eine vom Linux-Kernel verwendete Parameterdarstellungs- und Übertragungstechnologie. Bei der Initialisierung des Geräts während der Systemstartphase werden die im Gerätebaum beschriebenen Hardwareinformationen an das Betriebssystem übertragen

  • dts (Gerätebaumquelle): Gerätebaum-Quelldatei, die Geräteinformationen beschreibt;

    Die Gerätebaum-Quelldatei dts wird in eine DTB-Binärdatei kompiliert, die an das Betriebssystem übergeben wird, wenn der Bootloader ausgeführt wird, und das Betriebssystem Das System analysiert und erweitert es, um ein Topologiediagramm des Hardwaregeräts zu generieren. Mit diesem Topologiediagramm können die Knoten- und Attributinformationen des Gerätebaums während des Kompilierungsprozesses direkt über die vom System bereitgestellte Schnittstelle abgerufen werden dtc (Gerätebaum-Compiler): Gerätebaum-Kompilierungs-/Dekompilierungs-/Debugging-Tool;


  • dtb (Gerätebaum-Binärdatei): binäres Gerätebaum-Image;
  • dtsi (Gerätebaum-Quellen-Include): eine Header-Datei, die wie folgt funktioniert: eine Gerätebaumdatei und kann von der dts-Datei über include, dtsi referenziert werden. Die Datei beschreibt im Allgemeinen den gemeinsamen Teil
  • Im Gerätetreiber Der Quellcode ist in Treibercode und Gerätecode unterteilt. Der Treibercode ist die Methode zum Betreiben der Hardware, und der Gerätecode ist die Hardware-Ressource und die Daten, wenn der Treibercode und der Gerätecode übereinstimmen aufgerufen. Die Sondenfunktion verwendet die Ressourcen des Gerätecodes, um das Gerät zu initialisieren.

Vor dem Gerätebaum wird der Gerätecode direkt in den Kernel geschrieben. Im Quellcode liegt er in der Form „platform_device“ vor. Der Treibercode und der Gerätecode werden auch auf dem Plattformbus abgeglichen. Wenn die Geräteressourcen geändert werden müssen, muss der Kernel-Quellcode geändert werden.

Die Gerätebaumtechnologie konvertiert die Hardwareressourceninformationen des Geräts Schreiben Sie es in die DTS-Datei. Ändern Sie die DTS-Datei, ohne den Kernel-Quellcode zu ändern.

  • verwendet keine Gerätebaumtechnologie: Der Kernel-Quellcode wird mit einer großen Menge an Gerätehardware gefüllt Beschreibungsinformationen, was dazu führt, dass der Kernel-Quellcode weiter zunimmt, aber der Hardware-Beschreibungsinformationscode hat nichts mit der Kernelfunktion zu tun

  • Nach Verwendung der Gerätebaumtechnologie: Die Hardwarebeschreibungsinformationen des Geräts befinden sich im DTS Datei, die leicht zu ändern ist, aber der Kernel muss Code hinzufügen, um das DTS-Dateiformat zu analysieren.

  • 3 Wie funktioniert der Gerätebaum? Ändern Sie die DTS-Dateien entsprechend der Hardware, damit der zukünftige Treibercode mit den entsprechenden Gerätehardwareinformationen übereinstimmen kann.

  • Beim Kompilieren des Kernels kompiliert der Kernel zuerst DTC und verwendet dann DTC, um die DTS-Datei in DTB zu kompilieren

  • Wenn uboot den Kernel startet, verschiebt es das Kernel-Image und die dtb in den Speicher und teilt dem Kernel die Speicheradresse der dtb mit.
  • In der frühen Phase des Kernel-Starts wird die interne Funktion zum Parsen aufgerufen die dtb, und nach Erhalt der Hardware-Informationen wird sie zu einer Hardware-Funktion zusammengesetzt und schließlich mit dem Treibercode abgeglichen

4 Erläuterung des Gerätebaum-Quellcodes dts-Dateiformat

Was nützt Linux DTS?

  • 4.1. Der Speicherort von DTS-Dateien im Kernel-Quellcode
  • Arm-Architektur: im Verzeichnis arch/arm/boot/dts
  • 4.2. Einführung in das DTS-Dateiformat

Für Kommentare +

/dts-v1/node stellt die Versionsnummer von dts dar, die derzeit v1 ist.

/{} ist der Wurzelknoten sagte, dass dtc alle Wurzelknoten zu demselben zusammenführen wird.

dts ist eine baumartige Multi-Knoten-Organisation. Die Grundeinheit ist Knoten. Außer dem Stammknoten können auch andere Knoten vorhanden sein 4.3, Knotenformat 4.3.1. Formatdefinition []: gibt an, dass das Element weggelassen werden kann , : zeigt an, dass es nicht weggelassen werden kann;

[label:] : label ist der Labelname. Um den Zugriff auf den Knoten zu erleichtern, können Sie später über &label direkt auf den Knoten zugreifen.

  • node-name:节点名称。根节点的名称必须是/

  • [@unit-address]:unit-address是设备地址,如cpu node就是0、1这种,reg node就是0x12010000这种;

  • 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>;
    	};
    };
    • cpus是cpu的父节点,从形式来能直观的看出来,cpu节点是被cpus节点的大括号括起来的;

    • cpus节点省略了标签名和设备地址,只有节点名称;

    5、节点属性分析

    5.1、GPIO属性格式

    /{
    	gpx1:gpx1{
    		controller;
    		#gpio-cells=<2>;
    	};
    	
    	key@11400c24{
    		compatible="fs4412,key";
    		reg=<0x11400c24 0x4>;
    		intn-key=<&gpx1 2 2>;
    	}
    }
    • gpio-controller:说明该节点描述的是一个gpio控制器;

    • #gpio-cells:描述gpio使用节点的属性一个cell的内容;

    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 = ;
    	};};

    (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*/
    };
    • reg属性:配置某个硬件模块对应的地址范围信息;

    • #address-cells属性:表示reg里面的数据address占用的字长,注意字长不是字节;

    • #size-cells:表示reg里面的数据size占用的字长,注意字长不是字节;

    • reg = :address一般用来表示起始地址,length一般表示持续长度;

    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视频教程

    Das obige ist der detaillierte Inhalt vonWas nützt Linux DTS?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn