Device Tree (2): Basic concepts

Publisher:石头上种庄稼Latest update time:2023-09-30 Source: elecfansKeywords:Device Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

I. Introduction

For some background knowledge (for example: why Device Tree is introduced and what problem this mechanism is used to solve), please refer to the reasons for introducing Device Tree . This article mainly introduces the basic concepts of Device Tree.

Simply put, if you want to use Device Tree, you must first understand your own hardware configuration and system operating parameters, and organize this information into a Device Tree source file. Through DTC (Device Tree Compiler), these Device Tree source files suitable for human reading can be turned into Device Tree binary files suitable for machine processing (with a better name, DTB, device tree blob). When the system starts, the boot program (for example: firmware, bootloader) can copy the DTB saved in the flash to the memory (of course, it can also be loaded in other ways, such as loading the DTB through the interactive command of the bootloader, or the firmware can detect device information, organized into DTB and stored in memory), and the starting address of the DTB is passed to the client program (such as OS kernel, bootloader or other special function programs). For computer systems, it is usually firmware->bootloader->OS. For embedded systems, it is usually bootloader->OS.

This article mainly describes the following two topics:

1. Introduction to Device Tree source file syntax

2. Introduction to Device Tree binaryfile format

 

2. Structure of Device Tree

Before describing the structure of Device Tree, we first ask a basic question: Does Device Tree describe all hardware information in the system? the answer is negative. Basically, devices that can be detected dynamically do not need to be described, such as USB devices. However, for the USB host controller on the SOC, it cannot be dynamically recognized and needs to be described in the device tree. By the same token, in a computer system, PCI devices can be dynamically detected and do not need to be described in the device tree. However, if the PCI bridge cannot be detected, then it needs to be described.

In order to understand the structure of Device Tree, we first give an example of Device Tree:

/o device-tree 
      |- name = "device-tree" 
      |- model = "MyBoardName" 
      |- compatible = "MyBoardFamilyName" 
      |- #address-cells = <2> 
      |- #size-cells = <2> 
      |- linux,phandle = <0> 
      | 
      o cpus 
      | | - name = "cpus" 
      | | - linux,phandle = <1> 
      | | - #address-cells = <1> 
      | | - #size-cells = <0> 
      | | 
      | o PowerPC,970@0 
      | |- name = "PowerPC,970" 
      | |- device_type = "cpu" 
      | |- reg = <0> 
      | |- clock-frequency = <0x5f5e1000> 
      | |- 64- bit 
      | |- linux,phandle = <2> 
      | 
      o memory@0 
      | |- name = "memory" 
      | |- device_type = "memory" 
      | |- reg = <0x00000000 0x00000000 0x00000000 0x20000000>
      | |- linux,phandle = <3> 
      | 
      o chosen 
        |- name = "chosen" 
        |- bootargs = "root=/dev/sda2" 
        |- linux,phandle = <4>

As can be seen from the above figure, the basic unit of the device tree is node. These nodes are organized into a tree structure. Except for the root node, each node has only one parent. There can only be one root node in a device tree file. Each node contains several properties/values ​​to describe some characteristics of the node. Each node is identified by a node name. The format of the node name is node-name@unit-address . If the node does not have a reg attribute (this property will be described later), then the node name must not include @ and unit-address. The specific format of unit-address is related to which bus the device is connected to. For example, for a CPU, its unit-address starts from 0 and is increased by one. For a specific device, such as an Ethernet controller, its unit-address is the register address. The node name of the root node is certain and must be "/".

In a tree-structured device tree, how to reference a node? To uniquely specify a node, you must use the full path, such as /node-name-1/node-name-2/node-name-N. In the above example, the cpu node can be accessed through /cpus/PowerPC,970@0.

The property value identifies the characteristics of the device, and its values ​​are diverse:

1. It may be empty, that is, there is no definition of value. For example, for 64-bit in the picture above, this attribute has no value assigned.

2. It may be a u32 or u64 value (it is worth mentioning that the term cell represents a 32-bit information unit in Device Tree). For example #address-cells = <1>. Of course, it could be an array. For example <0x00000000 0x00000000 0x00000000 0x20000000>

4. It may be a string. For example, device_type = "memory", of course it may also be a string list. For example "PowerPC,970"

 

3. Introduction to Device Tree source file syntax

After understanding the basic device tree structure, we always need to reflect these structures in the device tree source code. In the Linux kernel, the file with the extension dts is the device tree source file that describes the hardware information. In the dts file, a node is defined as:

[label:] node-name[@unit-address] { 
   [properties definitions] 
   [child nodes] 
}

"[]" represents option, so you can define an empty node with only node name. Label is convenient for referencing in dts files, which will be described later. The format of child node is exactly the same as node. Therefore, a dts file contains several nested descriptions of node, property, child note, and child note property.

Considering that it is boring to talk about it in general, we use examples to explain the data format of Device Tree Source file. Assume that Wowo Technology has produced a S3C2416 development board, and we name the development board snail, then we need to write a file s3c2416-snail.dts. It is unreasonable to describe all the hardware information (SOC and peripherals) of the development board in one file, so it is possible that other companies also use S3C2416 to build their own development boards and command pig, cow, etc., if everyone If you use your own dts file to describe the hardware, most of it is repeated, so we save the hardware description related to S3C2416 into a separate dts file that can be referenced by the target board using S3C2416 and change the file extension to dtsi. (i means include). In the same way, Samsung's S3C24xx series is a SOC family. These SOCs (2410, 2416, 2450, etc.) also have the same content. Therefore, for the same reason, we can extract the public part and turn it into s3c24xx.dtsi, which is convenient for everyone to include. . In the same way, various ARM vendors will also share some hardware definition information. This file is skeleton.dtsi. We analyze them one by one from bottom to top (similar to from base class to top-level derived class in C++).

1. skeleton.dtsi. It is located in the linux-3.14archarmbootdts directory. The specific contents of this file are as follows:

/ { 
    #address-cells = <1>; 
    #size-cells = <1>; 
    chosen { }; 
    aliases { }; 
    memory { device_type = "memory"; reg = <0 0>; }; 
};

As the name suggests, device tree is a tree-like structure. Since it is a tree, it must have roots. "/" is the node name of the root node. The content between "{" and "}" is the specific definition of the node, which includes the definition of various attributes and the definition of child node. Chosen, aliases, and memory are all sub nodes. The structure of the sub node is exactly the same as the root node. Therefore, the sub node also has its own attributes and its own sub nodes, ultimately forming a tree-like device tree. The definition of attributes takes the form of property = value. For example, #address-cells and #size-cells are properties, and <1> is value. There are three situations for value:

1) The attribute value is text string or string list, expressed in double quotes. For example device_type = "memory"

2) The attribute value is 32bit unsigned integers, represented by angle brackets. For example #size-cells = <1>

3) The attribute value is binary data, expressed in square brackets. For example binary-property = [0x01 0x23 0x45 0x67]

If a device node contains a sub node that has addressing requirements (reg property needs to be defined) (child node may be used later, which has the same meaning as sub node), then these two properties must be defined. "#" means number. The #address-cells attribute is used to describe the address domain characteristics of the reg attribute in the sub node, that is, how many u32 cells are needed to describe the address domain. In the same way, the meaning of #size-cells can be inferred. More detailed information will be given in the description of reg below.

The chosen node is mainly used to describe the runtime parameters specified by the system firmware. If the chosen node exists, its parent node must be the root node with the name "/". It turns out that some Linux kernel runtime parameters passed through tag list can be passed through Device Tree. For example, the command line can be passed through the property of bootargs; the start address of initrd can also be passed through the property of linux, initrd-start. In this example, the chosen node is empty. In practice, it is recommended to add a bootargs attribute, for example:

"root=/dev/nfs nfsroot=1.1.1.1:/nfsboot ip=1.1.1.2:1.1.1.1:1.1.1.1:255.255.255.0::usbd0:off console=ttyS0,115200 mem=64M@0x30000000"

Through this command line, the kernel can be controlled to start from usbnet. Of course, the command line must be modified accordingly for specific projects to adapt to different needs. We know that device tree is used for HW platform identification, runtime parameter transfer and hardware device description. The chosen node does not describe any hardware device node information, it just passes the runtime parameter.

The aliases node defines some aliases. Why do we need to define this node? Because the Device tree is a tree structure, when you want to reference a node, you must specify the full path relative to the root node, such as /node-name-1/node-name-2/node-name-N. If referenced multiple times, it is somewhat troublesome to write such a complex string each time, so you can define some abbreviations of the full path of the device node in the aliases node. There are no aliases defined in skeleton.dtsi, and they will be further described with specific examples in the following section.

[1] [2] [3]
Keywords:Device Reference address:Device Tree (2): Basic concepts

Previous article:Serial port 0 is used as a debugging port, how to change it to a receiving data interface?
Next article:Port linux-3.0 to FL2440 (only basic porting)

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号