您的位置:首页 > 其它

【转】Device Tree Usage (设备树…

2013-11-01 09:26 357 查看
http://www.devicetree.org/Device_Tree_Usage#PCI_Address_Translation

This page walks through how to write a device tree for a new
machine. It is intended to provide an overview of device tree
concepts and how they are used to describe a machine.

本文将介绍如何为一个新机器编写设备树。我们准备提供一个有关设备树概念的概述和如何使用这些设备树来描述一个机器。

For a full technical description of device tree data format,
refer to the ePAPR specification. The ePAPR specification covers a
lot more detail than the basic topics covered on this page, please
refer to it for more advanced usage that isn't covered by this
page.

完整的设备树数据格式的技术说明书请参考
ePAPR 规范。ePAPR
规范涵盖了比本文基本主题更丰富的细节,要查阅本文没有涉及到的高级用法请参考该规范。

点击(此处)折叠或打开

     
    Contents

     
   
  目录

1 Basic Data Format

  基本数据格式

2 Basic Concepts

  基本概念

  2.1 Sample Machine

  2.2 Initial structure

  2.3 CPUs

  2.4 Node Names

  2.5 Devices

  2.6 Understanding the compatible Property

3 How Addressing Works

  如何编址

  3.1 CPU addressing

  3.2 Memory Mapped Devices

  3.3 Non Memory Mapped Devices

  3.4 Ranges (Address Translation)

4 How Interrupts Work

  中断的工作方式

5 Device Specific Data

  设备特定数据

6 Special Nodes

  特殊的节点

  6.1 aliases Node

  6.2 chosen Node

7 Advanced Topics

  高级主题

  7.1 Advanced Sample Machine

  7.2 PCI Host Bridge

    7.2.1 PCI Bus
numbering

    7.2.2 PCI Address
Translation

  7.3 Advanced Interrupt Mapping

8 Notes

  附注

Basic Data Format

基本数据格式

-----------------------------------------

The device tree is a simple tree structure of nodes and
properties. Properties are key-value pairs, and node may contain
both properties and child nodes. For example, the following is a
simple tree in the .dts format:

设备树是一个包含节点和属性的简单树状结构。属性就是键-值对,而节点可以同时包含属性和子节点。例如,以下就是一个
.dts 格式的简单树:

/ {

    node1 {

  
    
a-string-property = "A string";

  
    
a-string-list-property = "first string", "second string";

   
   
a-byte-data-property = [0x01 0x23 0x34 0x56];

   
    child-node1
{

  
      
  first-child-property;

   
     
  second-child-property =
<1>;

   
     
  a-string-property =
"Hello, world";

   
    };

   
    child-node2
{

  
     };

 
  };

 
  node2 {

  
     an-empty-property;

   
    a-cell-property
= <1 2 3 4>;

  
     child-node1
{

   
    };

 
  };

};

This tree is obviously pretty useless because it doesn't
describe anything, but it does show the structure of nodes an
properties. There is:

这棵树显然是没什么用的,因为它并没有描述任何东西,但它确实体现了节点的一些属性:

 ■ a single root node:
"/"

 
  一个单独的根节点:“/”

 ■ a couple of child
nodes: "node1" and "node2"

 
  两个子节点:“node1”和“node2”

 ■ a couple of children
for node1: "child-node1" and "child-node2"

 
  两个 node1
的子节点:“child-node1”和“child-node2”

 ■ a bunch of properties
scattered through the tree.

 
  一堆分散在树里的属性。

Properties are simple key-value pairs where the value can either
be empty or contain an arbitrary byte stream. While data types are
not encoded into the data structure, there are a few fundamental
data representations that can be expressed in a device tree source
file.

属性是简单的键-值对,它的值可以为空或者包含一个任意字节流。虽然数据类型并没有编码进数据结构,但在设备树源文件中任有几个基本的数据表示形式。

 ■ Text strings (null
terminated) are represented with double quotes:

 
  文本字符串(无结束符)可以用双引号表示:

string-property = "a string"

 ■ 'Cells' are 32 bit
unsigned integers delimited by angle brackets:

 
  ‘Cells’是 32
位无符号整数,用尖括号限定:

cell-property = <0xbeef 123
0xabcd1234>

 ■ binary data is
delimited with square brackets:

 
  二进制数据用方括号限定:

binary-property = [0x01 0x23 0x45 0x67];

 ■ Data of differing
representations can be concatenated together using a comma:

 
  不同表示形式的数据可以使用逗号连在一起:

mixed-property = "a string", [0x01 0x23 0x45 0x67],
<0x12345678>;

 ■ Commas are also used
to create lists of strings:

 
  逗号也可用于创建字符串列表:

string-list = "red fish", "blue fish";

Basic Concepts

基本概念

-----------------------------------------

To understand how the device tree is used, we will start with a
simple machine and build up a device tree to describe it step by
step.

我们将以一个简单机开始,然后通过一步步的建立一个描述这个简单机的设备树,来了解如何使用设备树。



Sample
Machine


模型机

Consider the following imaginary machine (loosely based on ARM
Versatile), manufactured by "Acme" and named "Coyote's
Revenge":

考虑下面这个假想的机器(大致基于ARM
Versatile),制造商为“Acme”,并命名为“Coyote's
Revenge”:

 ■ One 32bit ARM CPU

 
  一个 32 位 ARM CPU

 ■ processor local bus
attached to memory mapped serial port, spi bus controller, i2c
controller, interrupt controller, and external bus bridge

 
  处理器本地总线连接到内存映射的串行口、spi
总线控制器、i2c
控制器、中断控制器和外部总线桥

 ■ 256MB of SDRAM based
at 0

 
  256MB SDRAM 起始地址为 0

 ■ 2 Serial ports based
at 0x101F1000 and 0x101F2000

 
  两个串口起始地址:0x101F1000 和
0x101F2000

 ■ GPIO controller based
at 0x101F3000

 
  GPIO
控制器起始地址:0x101F3000

 ■ SPI controller based
at 0x10170000 with following devices

 
  带有以下设备的 SPI
控制器起始地址:0x10170000

   
 ■ MMC slot with SS pin
attached to GPIO #1

     
  MMC 插槽的 SS 管脚连接至 GPIO
#1

 ■ External bus bridge
with following devices

 
  外部总线桥挂载以下设备

   
 ■ SMC SMC91111 Ethernet
device attached to external bus based at 0x10100000

     
  SMC SMC91111
以太网设备连接到外部总线,起始地址:0x10100000

   
 ■ i2c controller based
at 0x10160000 with following devices

     
  i2c
控制器起始地址:0x10160000,并挂载以下设备

     
   ■ Maxim DS1338 real
time clock. Responds to slave address 1101000 (0x58)

     
   
  Maxim DS1338 实时时钟。响应至从地址
1101000 (0x58)

   
 ■ 64MB of NOR flash
based at 0x30000000

     
  64MB NOR 闪存起始地址 0x30000000

Initial
structure


初始结构

The first step is to lay down a skeleton structure for the
machine. This is the bare minimum structure required for a valid
device tree. At this stage you want to uniquely identify the
machine.

第一步就是要为这个模型机构建一个基本结构,这是一个有效的设备树最基本的结构。在这个阶段你需要唯一的标识该机器。

/ {

 
  compatible = "acme,coyotes-revenge";

};

compatible specifies the name of the system. It contains a
string in the form
"<manufacturer>,<model>.
It is important to specify the exact device, and to include the
manufacturer name to avoid namespace collisions. Since the
operating system will use the compatible value to make decisions
about how to run on the machine, it is very important to put
correct data into this property.

compatible
指定了系统的名称。它包含了一个“<制造商>,<型号>”形式的字符串。重要的是要指定一个确切的设备,并且包括制造商的名子,以避免命名空间冲突。由于操作系统会使用
compatible
的值来决定如何在机器上运行,所以正确的设置这个属性变得非常重要。

Theoretically, compatible is all the data an OS needs to
uniquely identify a machine. If all the machine details are hard
coded, then the OS could look specifically for
"acme,coyotes-revenge" in the top level compatible property.

理论上讲,兼容性(compatible)就是操作系统需要的所有数据都唯一标识一个机器。如果机器的所有细节都是硬编码的,那么操作系统则可以在顶层的
compatible
属性中具体查看“acme,coyotes-revenge”。

CPUs

中央处理器

Next step is to describe for each of the CPUs. A container node
named "cpus" is added with a child node for each CPU. In this case
the system is a dual-core Cortex A9 system from ARM.

接下来就应该描述每个 CPU
了。先添加一个名为“cpus”的容器节点,然后为每个
CPU 分别添加子节点。具体到我们的情况是一个 ARM
的 双核 Cortex A9 系统。

/ {

    compatible =
"acme,coyotes-revenge";

 
  cpus {

 
   
  cpu@0 {

   
     
  compatible =
"arm,cortex-a9";

   
    };

 
  
   cpu@1
{

 
  
    
  compatible =
"arm,cortex-a9";

  
     };

 
  };

};

The compatible property in each cpu node is a string that
specifies the exact cpu model in the form
<manufacturer>,<model>,
just like the compatible property at the top level.

每个 cpu 节点的 compatible
属性是一个“<制造商>,<型号>”形式的字符串,并指定了确切的
cpu,就像顶层的 compatible 属性一样。

More properties will be added to the cpu nodes later, but we
first need to talk about more of the basic concepts.

稍后将会有更多的属性添加进 cpu
节点,但我们先得讨论一些更过的基本概念。

Node
Names


节点名称

It is worth taking a moment to talk about naming conventions.
Every node must have a name in the form
<name>[@<unit-address>].

现在应该花点时间来讨论命名约定了。每个节点必须有一个“<名称>[@<设备地址>]”形式的名字。

<name> is a simple ascii string
and can be up to 31 characters in length. In general, nodes are
named according to what kind of device it represents. ie. A node
for a 3com Ethernet adapter would be use the name ethernet, not
3com509.

<名称>
就是一个不超过31位的简单 ascii
字符串。通常,节点的命名应该根据它所体现的是什么样的设备。比如一个
3com 以太网适配器的节点就应该命名为
ethernet,而不应该是 3com509。

The unit-address is included if the node describes a device with
an address. In general, the unit address is the primary address
used to access the device, and is listed in the node's reg
property. We'll cover the reg property later in this document.

如果该节点描述的设备有一个地址的话就还应该加上设备地址(unit-address)。通常,设备地址就是用来访问该设备的主地址,并且该地址也在节点的
reg 属性中列出。本文档中我们将在稍后涉及到 reg
属性。

Sibling nodes must be uniquely named, but it is normal for more
than one node to use the same generic name so long as the address
is different (ie, serial@101f1000 &
serial@101f2000).

See section 2.2.1 of the ePAPR spec for full details about node
naming.

同级节点命名必须是唯一的,但只要地址不同,多个节点也可以使用一样的通用名称(例如
serial@101f1000 和
serial@101f2000)。关于节点命名的更多细节请参考
ePAPR 规范 2.2.1 节。

Devices

设备

Every device in the system is represented by a device tree node.
The next step is to populate the tree with a node for each of the
devices. For now, the new nodes will be left empty until we can
talk about how address ranges and irqs are handled.

系统中每个设备都表示为一个设备树节点。所以接下来就应该为这个设备树填充设备节点。现在,知道我们讨论如何进行寻址和中断请求如何处理之前这些新节点将一直为空。

点击(此处)折叠或打开

/ {

    compatible =
"acme,coyotes-revenge";

    cpus {

     
  cpu@0 {

     
      compatible
= "arm,cortex-a9";

     
  };

     
  cpu@1 {

     
      compatible
= "arm,cortex-a9";

     
  };

    };

 
  serial@101F0000 {

 
      compatible
= "arm,pl011";

 
  };

 
  serial@101F2000 {

 
      compatible
= "arm,pl011";

 
  };

 
  gpio@101F3000 {

 
      compatible
= "arm,pl061";

 
  };

 
  interrupt-controller@10140000 {

 
      compatible
= "arm,pl190";

 
  };

 
  spi@10115000 {

 
      compatible
= "arm,pl022";

 
  };

 
  external-bus {

 
     
ethernet@0,0 {

 
     
    compatible =
"smc,smc91c111";

 
     
};

 
      i2c@1,0
{

 
     
    compatible =
"acme,a1234-i2c-bus";

 
     
    rtc@58 {

 
     
     
  compatible = "maxim,ds1338";

 
     
    };

 
     
};

 
      flash@2,0
{

 
     
    compatible =
"samsung,k8f1315ebm", "cfi-flash";

 
     
};

 
  };

};

<
d887
br />

In this tree, a node has been added for each device in the
system, and the hierarchy reflects the how devices are connected to
the system. ie. devices on the extern bus are children of the
external bus node, and i2c devices are children of the i2c bus
controller node. In general, the hierarchy represents the view of
the system from the perspective of the CPU.

在此树中,已经为系统中的每个设备添加了节点,而且这个·层次结构也反映了设备与系统的连接方式。例如,外部总线上的设备就是外部总线节点的子节点,i2c
设备就是 i2c
总线节点的子节点。通常,这个层次结构表现的是
CPU 视角的系统视图。

This tree isn't valid at this point. It is missing information
about connections between devices. That data will be added
later.

现在这棵树还是无效的,因为它缺少关于设备之间互联的信息。稍后将添加这些信息。

Some things to notice in this tree:

在这颗树中,应该注意这些事情:

 ■ Every device node has
a compatible property.

 
  每个设备节点都拥有一个 compatible
属性。

 ■ The flash node has 2
strings in the compatible property. Read on to the next section to
learn why.

 
  闪存(flash)节点的 compatible
属性由两个字符串构成。欲知为何,请阅读下一节。

 ■ As mentioned earlier,
node names reflect the type of device, not the particular model.
See section 2.2.2 of the ePAPR spec for a list of defined generic
node names that should be used wherever possible.

 
  正如前面所述,节点的命名应当反映设备的类型而不是特定的型号。请查阅
ePAPR 规范第 2.2.2
节里定义的通用节点名,应当优先使用这些节点名。

Understanding the compatible
Property


理解
compatible 属性


Every node in the tree that represents a device is required to
have the compatible property. compatible is the key an operating
system uses to decide which device driver to bind to a device.

树中每个表示一个设备的节点都需要一个
compatible 属性。compatible
属性是操作系统用来决定使用哪个设备驱动来绑定到一个设备上的关键因素。

compatible is a list of strings. The first string in the list
specifies the exact device that the node represents in the form
"<manufacturer>,<model>".
The following strings represent other devices that the device is
compatible with.

compatible
是一个字符串列表,之中第一个字符串指定了这个节点所表示的确切的设备,该字符串的格式为:"<制造商>,<型号>"。剩下的字符串的则表示其它与之相兼容的设备。

For example, the Freescale MPC8349 System on Chip (SoC) has a
serial device which implements the National Semiconductor ns16550
register interface. The compatible property for the MPC8349 serial
device should therefore be: compatible = "fsl,mpc8349-uart",
"ns16550". In this case, fsl,mpc8349-uart specifies the exact
device, and ns16550 states that it is register-level compatible
with a National Semiconductor 16550 UART.

例如,Freescale MPC8349
片上系统(SoC)拥有一个实现了美国国家半导体
ns16550 的寄存器接口的串行设备,那么 MPC8349
的串行设备的 compatible 属性就应该是:compatible =
"fsl,mpc8349-uart", "ns16550"。在这里,mpc8349-uart
指定了确切的设备,而 ns16550
则说明这是与美国国家半导体
ns16550 UART 的寄存器级兼容。

Note: ns16550 doesn't have a manufacturer prefix purely for
historical reasons. All new compatible values should use the
manufacturer prefix.

注:ns16550
并没有制造商前缀,这仅仅是历史原因造成的。所有的新
compatible 值都应该使用制造商前缀。

This practice allows existing device drivers to be bound to a
newer device, while still uniquely identifying the exact
hardware.

这种做法可以使现有的设备驱动能够绑定到新设备上,并仍然唯一的指定确切的设备。

Warning: Don't use wildcard compatible values, like
"fsl,mpc83xx-uart" or similar. Silicon vendors will invariably make
a change that breaks your wildcard assumptions the moment it is too
late to change it. Instead, choose a specific silicon
implementations and make all subsequent silicon compatible with
it.

警告:不要使用带通配符的 compatible
值,比如“fsl,mpc83xx-uart”或类似情况。芯片提供商无不会做出一些能够轻易打破你通配符猜想的变化,这时候在修改已经为时已晚了。相反,应该选择一个特定的芯片然后是所有后续芯片都与之兼容。

How
Addressing Works

如何编址

-----------------------------------------

Devices that are addressable use the following properties to
encode address information into the device tree:

可编址设备使用以下属性将地址信息编码进设备树:

 ■ reg

 ■ #address-cells

 ■ #size-cells

Each addressable device gets a reg which is a list of tuples in
the form reg = <address1 length1 [address2 length2]
[address3 length3] ... >. Each tuple represents an
address range used by the device. Each address value is a list of
one or more 32 bit integers called cells. Similarly, the length
value can either be a list of cells, or empty.

每个可编址设备都有一个元组列表的
reg,元组的形式为:reg = <地址1 长度1
[地址2 长度2]
[地址3 长度3] ...
>。每个元组都表示一个该设备使用的地址范围。每个地址值是一个或多个
32 位整型数列表,称为
cell。同样,长度值也可以是一个 cell
列表或者为空。

Since both the address and length fields are variable of
variable size, the #address-cells and #size-cells properties in the
parent node are used to state how many cells are in each field. Or
in other words, interpreting a reg property correctly requires the
parent node's #address-cells and #size-cells values. To see how
this all works, lets add the addressing properties to the sample
device tree, starting with the CPUs.

由于地址和长度字段都是可变大小的变量,那么父节点的
#address-cells 和 #size-cells 属性就用来声明各个字段的
cell 的数量。换句话说,正确解释一个 reg
属性需要用到父节点的 #address-cells 和 #size-cells
的值。要知道这一切是如何运作的,我们将给模型机添加编址属性,就从
CPU 开始。

CPU
addressing


CPU 编址

The CPU nodes represent the simplest case when talking about
addressing. Each CPU is assigned a single unique ID, and there is
no size associated with CPU ids.

CPU
节点表示了一个关于编址的最简单的例子。每个 CPU
都分配了一个唯一的 ID,并且没有 CPU id
相关的大小信息。

    cpus {

     
  #address-cells =
<1>;

 
     
#size-cells = <0>;

     
  cpu@0 {

     
      compatible
= "arm,cortex-a9";

     
   
  reg =
<0>;

     
  };

     
  cpu@1 {

     
      compatible
= "arm,cortex-a9";

     
   
  reg =
<1>;

     
  };

    };

In the cpus node, #address-cells is set to 1, and #size-cells is
set to 0. This means that child reg values are a single uint32 that
represent the address with no size field. In this case, the two
cpus are assigned addresses 0 and 1. #size-cells is 0 for cpu nodes
because each cpu is only assigned a single address.

在 cpu 节点中,#address-cells
设置为 1,#size-cells 设置为 0。这意味着子节点的
reg 值是一个单一的
uint32,这是一个不包含大小字段的地址,为这两个
cpu 分配的地址是 0 和 1。cpu 节点的 #size-cells 为 0
是因为只为每个 cpu 分配一个单独的地址。

You'll also notice that the reg value matches the value in the
node name. By convention, if a node has a reg property, then the
node name must include the unit-address, which is the first address
value in the reg property.

你可能还会注意到 reg
的值和节点名字是相同的。按照惯例,如果一个节点有
reg
属性,那么该节点的名字就必须包含设备地址,这个设备地址就是
reg 属性里第一个地址值。

Memory Mapped
Devices


内存映射设备

Instead of single address values like found in the cpu nodes, a
memory mapped device is assigned a range of addresses that it will
respond to. #size-cells is used to state how large the length field
is in each child reg tuple. In the following example, each address
value is 1 cell (32 bits), and each length value is also 1 cell,
which is typical on 32 bit systems. 64 bit machines may use a value
of 2 for #address-cells and #size-cells to get 64 bit addressing in
the device tree.

与 cpu
节点里单一地址值不同,应该分配给内存映射设备一个地址范围。#size-cells
声明每个子节点的 reg
元组中长度字段的大小。在接下来的例子中,每个地址值是
1 cell(32 位),每个长度值也是 1 cell,这是典型的
32 位系统。64 位的机器则可以使用值为 2 的
#address-cells 和 #size-cells 来获得在设备树中的 64
位编址。

/ {

 
  #address-cells =
<1>;

 
  #size-cells =
<1>;

    ...

    serial@101f0000 {

     
  compatible = "arm,pl011";

     
  reg = <0x101f0000 0x1000
>;

    };

    serial@101f2000 {

     
  compatible = "arm,pl011";

     
  reg = <0x101f2000 0x1000
>;

    };

    gpio@101f3000 {

     
  compatible = "arm,pl061";

     
  reg = <0x101f3000
0x1000

 
     
     
 0x101f4000 0x0010>;

    };

   
interrupt-controller@10140000 {

     
  compatible = "arm,pl190";

     
  reg = <0x10140000 0x1000
>;

    };

    spi@10115000 {

     
  compatible = "arm,pl022";

     
  reg = <0x10115000 0x1000
>;

    };

    ...

};

Each device is assigned a base address, and the size of the
region it is assigned. The GPIO device address in this example is
assigned two address ranges; 0x101f3000...0x101f3fff and
0x101f4000..0x101f400f.

每个设备都被分配了一个基址以及该区域的大小。这个例子中为
GPIO 分配了两个地址范围:0x101f3000...0x101f3fff 和
0x101f4000..0x101f400f。

Some devices live on a bus with a different addressing scheme.
For example, a device can be attached to an external bus with
discrete chip select lines. Since each parent node defines the
addressing domain for its children, the address mapping can be
chosen to best describe the system. The code below show address
assignment for devices attached to the external bus with the chip
select number encoded into the address.

一些挂在总线上的设备有不同的编址方案。例如一个带独立片选线的设备也可以连接至外部总线。由于父节点会为其子节点定义地址域,所以可以选择不同的地址映射来最恰当的描述该系统。下面的代码展示了设备连接至外部总线并将其片选号编码进地址的地址分配。

external-bus {

     
  #address-cells =
<2>

 
     
#size-cells = <1>;

     
  ethernet@0,0 {

     
      compatible
= "smc,smc91c111";

     
   
  reg = <0 0
0x1000>;

     
  };

     
  i2c@1,0 {

     
      compatible
= "acme,a1234-i2c-bus";

     
   
  reg = <1 0
0x1000>;

     
      rtc@58
{

     
     
    compatible =
"maxim,ds1338";

     
      };

     
  };

     
  flash@2,0 {

     
      compatible
= "samsung,k8f1315ebm", "cfi-flash";

     
   
  reg = <2 0
0x4000000>;

     
  };

    };

The external-bus uses 2 cells for the address value; one for the
chip select number, and one for the offset from the base of the
chip select. The length field remains as a single cell since only
the offset portion of the address needs to have a range. So, in
this example, each reg entry contains 3 cells; the chipselect
number,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: