A quoi sert Linux DTS

青灯夜游
青灯夜游original
2023-03-14 10:34:081532parcourir

Sous Linux, dts est un fichier source d'arborescence de périphériques, utilisé pour décrire les informations sur le périphérique. La technologie de l'arborescence de périphériques écrit les informations sur les ressources matérielles du périphérique dans le fichier dts. Le fichier source de l'arborescence des périphériques dts est compilé dans un binaire dtb et transmis au système d'exploitation lorsque le chargeur de démarrage est en cours d'exécution. Le système d'exploitation l'analyse et le développe pour générer un diagramme de topologie du périphérique matériel. Être directement transmis via L'interface fournie par le système obtient les informations sur les nœuds et les attributs de l'arborescence des périphériques.

A quoi sert Linux DTS

L'environnement d'exploitation de ce tutoriel : système linux7.3, ordinateur Dell G3.

1. Qu'est-ce qu'une arborescence d'appareils ?

L'arborescence des périphériques (dt : arborescence des périphériques) est une technologie de représentation et de transfert de paramètres utilisée par le noyau Linux lors de l'initialisation du périphérique pendant la phase de démarrage du système, les informations matérielles décrites dans l'arborescence des périphériques sont transférées au système d'exploitation ;

  • dts (device tree source) : fichier source de l'arborescence des périphériques, décrivant les informations sur le périphérique ;

    Le fichier source de l'arborescence des périphériques dts est compilé dans un binaire dtb, qui est transmis au système d'exploitation lorsque le chargeur de démarrage est en cours d'exécution, et le système d'exploitation Le système l'analyse et l'étend pour générer un diagramme de topologie du périphérique matériel. Avec ce diagramme de topologie, les informations sur les nœuds et les attributs de l'arborescence des périphériques peuvent être obtenues directement via l'interface fournie par le système pendant le processus de compilation


  • . dtc (compilateur d'arborescence de périphériques) : outil de compilation/décompilation/débogage d'arborescence de périphériques ;

  • dtb (binaire d'arborescence de périphériques) : image d'arborescence de périphériques binaires ;

  • dtsi (source d'arborescence de périphériques incluse) : un fichier d'en-tête qui fonctionne comme un fichier d'arborescence de périphériques et peut être référencé par le fichier dts via include, dtsi Le fichier décrit généralement la partie commune

2 Quel problème l'arborescence de périphériques résout-elle

  • Dans le pilote de périphérique ? code source, il est divisé en code du pilote et code du périphérique. Le code du pilote est la méthode de fonctionnement du matériel, et le code du périphérique est constitué de ressources matérielles et de données. Lorsque le code du pilote et le code du périphérique correspondent, la fonction de sonde du pilote sera. appelée.La fonction de sonde utilisera les ressources du code de l'appareil pour initialiser l'appareil ;

  • Avant l'arborescence des appareils, le code de l'appareil est écrit directement dans le noyau. Dans le code source, il existe sous la forme d'une structure platform_device. Le code du pilote et le code du périphérique correspondent également sur le bus de la plate-forme. Lorsque les ressources du périphérique doivent être modifiées, le code source du noyau doit être modifié.

  • La technologie de l'arborescence des périphériques convertit les informations sur les ressources matérielles du périphérique ; écrivez-le dans le fichier dts. Si vous devez le modifier, modifiez le fichier dts sans modifier le code source du noyau ;

  • n'utilise pas la technologie de l'arborescence des périphériques : le code source du noyau sera rempli d'une grande quantité de matériel de périphérique. informations de description, provoquant une augmentation continue du code source du noyau, mais l'augmentation Le code d'informations de description du matériel n'est pas lié à la fonction du noyau

  • Après avoir utilisé la technologie de l'arborescence des périphériques : les informations de description du matériel du périphérique sont dans le dts ; fichier, qui est facile à modifier, mais le noyau doit ajouter du code pour analyser le format de fichier dts ; modifier les fichiers dts en fonction du matériel afin que le futur code du pilote puisse correspondre aux informations matérielles appropriées du périphérique

Lors de la compilation du noyau, le noyau compilera d'abord dtc, puis utilisera dtc pour compiler le fichier dts en dtb ;

Lorsque uboot démarre le noyau, il déplace l'image du noyau et la dtb dans la mémoire, et indique au noyau l'adresse mémoire de la dtb

Au début du démarrage du noyau, la fonction interne est appelée pour analyser ; le dtb, et après avoir obtenu les informations matérielles, il est assemblé en une fonction matérielle, et finalement mis en correspondance avec le code du pilote A quoi sert Linux DTS

  • 4. Explication du format de fichier dts du code source de l'arborescence des périphériques ;
  • 4.1. L'emplacement de stockage des fichiers dts dans le code source du noyau

  • architecture arm : dans le répertoire arch/arm/boot/dts

4.2 Introduction au format de fichier dts.

Pour les commentaires + /dts-v1/node indique le numéro de version de dts, qui est actuellement v1/{} est le nœud racine. En théorie, il ne devrait y avoir qu'un seul nœud racine. a dit que dtc fusionnerait tous les nœuds racines dans le même

dts est une organisation multi-nœuds arborescente. L'unité de base est le nœud, à l'exception de la racine, les autres nœuds ont des parents et il peut aussi y avoir des enfants

. 4.3, format de nœud

  • 4.3.1. Définition du format

    [label:] <node-name> [@<unit-address>]{
      [property]
      [child nodes]
      [child nodes]
      ......
    };</unit-address></node-name>
  • 4.3.2 Interprétation du format
  • [. ] : indique que l'élément peut être omis ,  : indique qu'il ne peut pas être omis ;
  • [label:] : label est le nom de l'étiquette Afin de faciliter l'accès au nœud, vous pourrez accéder directement au nœud via &label ultérieurement.

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn