Notes d'étude sur le développement de pilotes Linux [3]: arborescence des périphériques

table des matières

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

2. La relation entre DTS, DTB et DTC

Troisièmement, la syntaxe de base DTS

Quatrièmement, créez un petit modèle d'arborescence de périphériques

Cinq, l'incarnation de l'arborescence des appareils dans le système

Six nœuds spéciaux

1, nœud d'alias

2. Le nœud choisi

Sept attributs spéciaux

1. Attribut compatible (attribut de compatibilité)

2. Attributs du modèle

3. Attribut d'état

4. # address-cells et # size-cells attributs

5. attribut reg

6, propriété de gammes

7, attribut device_type

Huit, la fonction d'opération OF du noyau Linux


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

Device Tree (Device Tree) . Séparant le mot en "device" et "tree", le fichier décrivant l'arborescence des périphériques s'appelle DTS (Device Tree Source), ce fichier DTS utilise une arborescence pour décrire les périphériques au niveau de la carte, c'est-à-dire la carte de développement Informations sur le périphérique, telles que le nombre de processeurs, l'adresse de base de la mémoire, les périphériques connectés à l'interface IIC, les périphériques connectés à l'interface SPI, etc., comme indiqué sur la figure:

 

2. La relation entre DTS, DTB et DTC

1. DTS est équivalent à .c, qui est le fichier source de l'arborescence des périphériques

2. L'outil DTC est équivalent au compilateur gcc, qui compile .dts en .dtb Le code source de l'outil DTC se trouve dans le répertoire scripts / dtc du noyau Linux.

3. DTB est un fichier binaire obtenu après la compilation de DTS

Compilez tous les fichiers dts par make dtbs

Vous pouvez également compiler les dtbs spécifiés, tels que: make imx6ull-alientek-emmc.dtb

Lors de la compilation du fichier dtb, vous pouvez spécifier le fichier source de l'arborescence des périphériques dts à compiler via \ arch \ arm \ boot \ dts \ Makefile

Troisièmement, la syntaxe de base DTS

L'arborescence des périphériques a également un fichier d'en-tête avec une extension .dtsi. Vous pouvez afficher les informations communes d'un SOC et de tous les autres appareils / plates-formes sous forme de fichier .dtsi commun

1, DTS également  start, / est l'ensemble du périphérique avec l'arborescence des nœuds

2. Décrivez les informations sur le périphérique à partir du nœud racine

 

3. Certaines instructions comme & cpu0 en dehors du nœud racine sont "ajoutées"

 

4. Dénomination des nœuds

label:node-name@unit-address

label: C'est le libellé du nœud, suivi du nom, il est facultatif, par exemple

intc: interrupt-controller@00a01000 完整的名字是interrupt-controller@00a01000

在后面追加的时候直接使用&intc

nom du nœud : nom du nœud

adresse-unité: généralement l'adresse de départ du registre périphérique, parfois c'est l'adresse de l'appareil de l'I2C, ou d'autres significations, analyse spécifique au nœud spécifique

Quatrièmement, créez un petit modèle d'arborescence de périphériques

/dts-v1

#include .h
#include .dtsi

/ {
    /* skeleton.dtsi文件*/
    #address-cells = <1>;
    #size-cells = <1>;
    
    chosen {
      stdout-path = &uart1;  
    };
    
    aliases {
	};

	cpus {
	};

	intc: interrupt-controller@00a01000 {
	};

	clocks {
	};

	soc {
	};
 
    memory {
    };
    
    reserved-memory{
    };
    
    ...
}

Cinq, l'incarnation de l'arborescence des appareils dans le système

Le noyau Linux analysera le fichier DTB au démarrage, puis générera le fichier de nœud de l'arborescence de périphériques correspondant dans le répertoire / proc / device-tree

Comment le noyau Linux analyse le fichier DTB, le processus est le suivant:

Six nœuds spéciaux

1, nœud d'alias

2. Le nœud choisi

Le but principal est de transmettre la valeur de la variable d'environnement bootargs dans uboot au noyau Linux en tant que paramètre de ligne de commande, ligne de commande . La valeur bootargs dans uboot est:

bootargs=console=ttymxc0,115200 root=/dev/nfs rw 
nfsroot=192.168.199.158:/home/denghengli/linux/nfs/rootfs ip=192.168.199.20:192.168.199.158:192.168.199.1:255.255.255.0::eth0:off
//说明:192.168.199.158为ubuntu主机ip,192.168.199.20为开发板ip

La valeur cmdline du noyau Linux est:

Kernel command line: console=ttymxc0,115200 root=/dev/nfs rw 
nfsroot=192.168.199.158:/home/denghengli/linux/nfs/rootfs ip=192.168.199.20:192.168.199.158:192.168.199.1:255.255.255.0::eth0:off

Alors, comment uboot passe-t-il les bootargs au noyau?

Après vérification, on constate que le nœud choisi contient l'attribut bootargs et que la valeur de l'attribut est cohérente avec les bootargs d'uboot. uboot a contacté dtb et a finalement démarré le noyau via bootz 80800000-83000000. Après analyse, il est jugé que uboot a la variable d'environnement bootargs et dtb, il est donc le plus susceptible de commettre des crimes. Enfin, on constate que le nœud choisi sera trouvé dans la fonction fdt_chosen d'uboot, et l'attribut bootargs y sera ajouté, et la valeur d'attribut est la valeur de la variable bootargs.

Sept attributs spéciaux

1. Attribut compatible (attribut de compatibilité)

(1) La valeur est une chaîne. L'attribut ompatible est utilisé pour lier le périphérique et le pilote. La liste de chaînes est utilisée pour sélectionner le pilote à utiliser par le périphérique. Le format de valeur de l'attribut compatible est le suivant: "fabricant, modèle", où le fabricant représente le fabricant, et modèle est généralement le nom du pilote correspondant au module. Par exemple, le nœud audio dans imx6ull-alientek-emmc.dts est le nœud de périphérique audio de la carte de développement i.MX6U-ALPHA:

compatible = "fsl,imx6ul-evk-wm8960","fsl,imx-audio-wm8960";
其中 fsl表示厂商是飞思卡尔,“imx6ul-evk-wm8960”和 imx-audio-wm8960”表示驱动模块名字。
sound这个设备首先使用第一个兼容值在 Linux内核里面查找,看看能不能找到与之匹配的驱动文件,
如果没有找到的话就使用第二个兼容值查。

(2) En général, le fichier du pilote aura une table de correspondance OF. Cette table de correspondance OF stocke certaines valeurs compatibles. Si la valeur d'attribut compatible du nœud de périphérique est égale à n'importe quelle valeur de la table de correspondance OF, alors le périphérique peut utiliser ce pilote. .

static const struct of_device_id imx_wm8960_dt_ids[] = {
	{ .compatible = "fsl,imx-audio-wm8960", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_wm8960_dt_ids);

static struct platform_driver imx_wm8960_driver = {
	.driver = {
		.name = "imx-wm8960",
		.pm = &snd_soc_pm_ops,
		.of_match_table = imx_wm8960_dt_ids,
	},
	.probe = imx_wm8960_probe,
	.remove = imx_wm8960_remove,
};
module_platform_driver(imx_wm8960_driver);

(3) Le nœud racine / compatible ci-dessous . Lorsque le noyau est démarré, il vérifiera s'il prend en charge cette plate-forme ou cette machine.

Lorsque l'arborescence des périphériques n'est pas utilisée, l'identifiant de la machine est utilisé pour déterminer si le noyau prend en charge cette machine:

#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
 __used \
 __attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \
.name = _name,
 
#define MACHINE_END \
};


MACHINE_START(MX35_3DS, "Freescale MX35PDK")
/* Maintainer: Freescale Semiconductor, Inc */
.atag_offset = 0x100,
.map_io = mx35_map_io,
.init_early = imx35_init_early,
.init_irq = mx35_init_irq,
.init_time = mx35pdk_timer_init,
.init_machine = mx35_3ds_init,
.reserve = mx35_3ds_reserve,
.restart = mxc_restart,
MACHINE_END


展开以后:
static const struct machine_desc __mach_desc_MX35_3DS __used
 __attribute__((__section__(".arch.info.init"))) = {
.nr = MACH_TYPE_MX35_3DS, //机器ID
.name = "Freescale MX35PDK",
.atag_offset = 0x100,
.map_io = mx35_map_io,
.init_early = imx35_init_early,
.init_irq = mx35_init_irq,
.init_time = mx35pdk_timer_init,
.init_machine = mx35_3ds_init,
.reserve = mx35_3ds_reserve,
.restart = mxc_restart,
};

Lors de l'utilisation de l'arborescence des périphériques, l'ID de la machine n'est pas utilisé, mais compatible sous le nœud racine /:

#define DT_MACHINE_START(_name, _namestr) \
static const struct machine_desc __mach_desc_##_name \
 __used \
 __attribute__((__section__(".arch.info.init"))) = { \
.nr = ~0, \
.name = _namestr,


DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
.map_io = imx6ul_map_io,
.init_irq = imx6ul_init_irq,
.init_machine = imx6ul_init_machine,
.init_late = imx6ul_init_late,
.dt_compat = imx6ul_dt_compat,
MACHINE_END


展开以后:
static const struct machine_desc __mach_desc_IMX6UL __used
 __attribute__((__section__(".arch.info.init"))) = {
.nr = ~0,
.name = "Freescale i.MX6 Ultralite (Device Tree)",
.map_io = imx6ul_map_io,
.init_irq = imx6ul_init_irq,
.init_machine = imx6ul_init_machine,
.init_late = imx6ul_init_late,
.dt_compat = imx6ul_dt_compat,
};

2. Attributs du modèle

La valeur de l'attribut de modèle est également une chaîne. En général, l'attribut de modèle décrit les informations du module de périphérique, telles que le nom, telles que:

model = "wm8960-audio";

3. Attribut d'état

L'attribut status est lié à l'état du périphérique en examinant le nom. La valeur de l'attribut status est également une chaîne, qui correspond aux informations d'état du périphérique. L'état facultatif est indiqué dans le tableau.

4. # address-cells et # size-cells attributs

Dans les appareils avec des nœuds enfants, il est utilisé pour décrire les informations d'adresse des nœuds enfants. La valeur d'attribut # address-cells détermine la longueur de mot (32 bits) occupée par les informations d'adresse dans l'attribut reg du nœud enfant, et la valeur d'attribut # size-cells détermine la longueur de mot (32 bits) occupée par les informations de longueur dans l'attribut reg du nœud enfant. # address-cells et # size-cells indiquent comment le nœud enfant doit écrire la valeur de l'attribut reg. En général, l'attribut reg est le contenu lié à l'adresse, et il existe deux types d'informations liées à l'adresse: l'adresse de début et la longueur de l'adresse, et l'attribut reg Le premier format est:

reg = <address1 length1 address2 length2 address3 length3…………>

5. attribut reg

Généralement utilisé pour décrire les informations de ressources d'espace d'adressage de périphérique, généralement les informations de plage d'adresses de registre d'un certain périphérique

reg = <0x4600 0x100>;

6, propriété de gammes

La valeur de l'attribut de plages peut être vide ou une matrice numérique écrite au format (adresse-bus-enfant, adresse-bus-parent, longueur), les plages est une table de mappage / conversion d'adresses, et chaque élément de l'attribut plages se compose de l'adresse enfant, de l'adresse parent et de l'adresse La longueur de l'espace se compose de trois parties:

child-bus-address : adresse physique de l'espace d'adressage du bus enfant. Les # cellules d'adresse du nœud parent déterminent la longueur de mot occupée par cette adresse physique.

parent-bus-address : L'adresse physique de l'espace d'adressage du bus parent et la longueur de mot occupée par cette adresse physique sont également déterminées par les # cellules d'adresse du nœud parent.

length : La longueur de l' espace de sous-adresse. Le # size-cells du nœud parent détermine la longueur de mot occupée par la longueur d'adresse.

Si la valeur d'attribut de plage est une valeur nulle, cela signifie que l'espace d'adressage secondaire est exactement le même que l'espace d'adressage parent et qu'aucune conversion d'adresse n'est requise.

7, attribut device_type

La valeur de l'attribut device_type est une chaîne, IEEE 1275 utilisera cet attribut pour décrire le FCode du périphérique, mais l'arborescence du périphérique n'a pas FCode, donc cet attribut est également abandonné. Cet attribut ne peut être utilisé que pour les nœuds de processeur ou les nœuds de mémoire. Le nœud cpu0 de imx6ull.dtsi utilise cet attribut

Huit, la fonction d'opération OF du noyau Linux

1. Si vous souhaitez obtenir les informations de noeud ou d'attribut dans l'arborescence des périphériques du pilote, vous devez utiliser la fonction OF. Les prototypes de ces fonctions OF sont définis dans le fichier include / linux / of.h.

2. Si le pilote souhaite obtenir le contenu du nœud de l'arborescence des périphériques, il doit d'abord trouver le nœud.

 

 

Je suppose que tu aimes

Origine blog.csdn.net/m0_37845735/article/details/106976651
conseillé
Classement