【转】Device Tree Usage (设备树…

来源:互联网 发布:淘宝tbc 编辑:程序博客网 时间:2024/06/05 02:34

http://www.devicetree.org/Device_Tree_Usage#PCI_Address_Translation

This page walks through how to write a device tree for a newmachine. It is intended to provide an overview of device treeconcepts 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 alot more detail than the basic topics covered on this page, pleaserefer to it for more advanced usage that isn't covered by thispage.


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





点击(此处)折叠或打开




  1.          Contents

  2.           目录

  3. 1 Basic Data Format

  4.   基本数据格式

  5. 2 Basic Concepts

  6.   基本概念

  7.   2.1 Sample Machine

  8.   2.2 Initial structure

  9.   2.3 CPUs

  10.   2.4 Node Names

  11.   2.5 Devices

  12.   2.6 Understanding the compatible Property

  13. 3 How Addressing Works

  14.   如何编址

  15.   3.1 CPU addressing

  16.   3.2 Memory Mapped Devices

  17.   3.3 Non Memory Mapped Devices

  18.   3.4 Ranges (Address Translation)

  19. 4 How Interrupts Work

  20.   中断的工作方式

  21. 5 Device Specific Data

  22.   设备特定数据

  23. 6 Special Nodes

  24.   特殊的节点

  25.   6.1 aliases Node

  26.   6.2 chosen Node

  27. 7 Advanced Topics

  28.   高级主题

  29.   7.1 Advanced Sample Machine

  30.   7.2 PCI Host Bridge

  31.     7.2.1 PCI Busnumbering

  32.     7.2.2 PCI AddressTranslation

  33.   7.3 Advanced Interrupt Mapping

  34. 8 Notes

  35.   附注





Basic Data Format


基本数据格式



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


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


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



  1. / {

  2.     node1 {

  3.       a-string-property = "A string";

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

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

  6.        child-node1{

  7.           first-child-property;

  8.           second-child-property =<1>;

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

  10.        };

  11.        child-node2{

  12.        };

  13.    };

  14.    node2 {

  15.        an-empty-property;

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

  17.        child-node1{

  18.        };

  19.    };

  20. };


This tree is obviously pretty useless because it doesn'tdescribe anything, but it does show the structure of nodes anproperties. There is:

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



 &#9632; a single root node:"/"


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


 &#9632; a couple of childnodes: "node1" and "node2"


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


 &#9632; a couple of childrenfor node1: "child-node1" and "child-node2"


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


 &#9632; a bunch of propertiesscattered through the tree.


   一堆分散在树里的属性。


Properties are simple key-value pairs where the value can eitherbe empty or contain an arbitrary byte stream. While data types arenot encoded into the data structure, there are a few fundamentaldata representations that can be expressed in a device tree sourcefile.


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


 &#9632; Text strings (nullterminated) are represented with double quotes:


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




  1. string-property = "a string"


 &#9632; 'Cells' are 32 bitunsigned integers delimited by angle brackets:


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




  1. cell-property = <0xbeef 1230xabcd1234>


 &#9632; binary data isdelimited with square brackets:


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




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


 &#9632; Data of differingrepresentations can be concatenated together using a comma:


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




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


 &#9632; Commas are also usedto create lists of strings:


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




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



Basic Concepts


基本概念


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


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


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





SampleMachine


模型机


Consider the following imaginary machine (loosely based on ARMVersatile), manufactured by "Acme" and named "Coyote'sRevenge":




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



 &#9632; One 32bit ARM CPU


   一个 32 位 ARM CPU



 &#9632; processor local busattached to memory mapped serial port, spi bus controller, i2ccontroller, interrupt controller, and external bus bridge



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



 &#9632; 256MB of SDRAM basedat 0


   256MB SDRAM 起始地址为 0


 &#9632; 2 Serial ports basedat 0x101F1000 and 0x101F2000


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


 &#9632; GPIO controller basedat 0x101F3000


   GPIO控制器起始地址:0x101F3000


 &#9632; SPI controller basedat 0x10170000 with following devices


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


    &#9632; MMC slot with SS pinattached to GPIO #1


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


 &#9632; External bus bridgewith following devices


   外部总线桥挂载以下设备


    &#9632; SMC SMC91111 Ethernetdevice attached to external bus based at 0x10100000


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


    &#9632; i2c controller basedat 0x10160000 with following devices


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


        &#9632; Maxim DS1338 realtime clock. Responds to slave address 1101000 (0x58)


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


    &#9632; 64MB of NOR flashbased at 0x30000000



       64MB NOR 闪存起始地址 0x30000000





Initialstructure


初始结构


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



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




  1. / {

  2.    compatible = "acme,coyotes-revenge";

  3. };



compatible specifies the name of the system. It contains astring in the form"<manufacturer>,<model>.It is important to specify the exact device, and to include themanufacturer name to avoid namespace collisions. Since theoperating system will use the compatible value to make decisionsabout how to run on the machine, it is very important to putcorrect data into this property.


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


Theoretically, compatible is all the data an OS needs touniquely identify a machine. If all the machine details are hardcoded, 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 nodenamed "cpus" is added with a child node for each CPU. In this casethe system is a dual-core Cortex A9 system from ARM.



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




  1. / {

  2.     compatible ="acme,coyotes-revenge";


  3.    cpus {

  4.       cpu@0 {

  5.           compatible ="arm,cortex-a9";

  6.        };

  7.       cpu@1{

  8.          compatible ="arm,cortex-a9";

  9.        };

  10.    };

  11. };



The compatible property in each cpu node is a string thatspecifies 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 wefirst need to talk about more of the basic concepts.



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





NodeNames


节点名称


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 stringand can be up to 31 characters in length. In general, nodes arenamed according to what kind of device it represents. ie. A nodefor a 3com Ethernet adapter would be use the name ethernet, not3com509.


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


The unit-address is included if the node describes a device withan address. In general, the unit address is the primary addressused to access the device, and is listed in the node's regproperty. 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 morethan one node to use the same generic name so long as the addressis different (ie, serial@101f1000 &serial@101f2000).


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



同级节点命名必须是唯一的,但只要地址不同,多个节点也可以使用一样的通用名称(例如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 thedevices. For now, the new nodes will be left empty until we cantalk about how address ranges and irqs are handled.



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






点击(此处)折叠或打开




  1. / {

  2.     compatible ="acme,coyotes-revenge";


  3.     cpus {

  4.        cpu@0 {

  5.            compatible= "arm,cortex-a9";

  6.        };

  7.        cpu@1 {

  8.            compatible= "arm,cortex-a9";

  9.        };

  10.     };


  11.    serial@101F0000 {

  12.        compatible= "arm,pl011";

  13.    };


  14.    serial@101F2000 {

  15.        compatible= "arm,pl011";

  16.    };


  17.    gpio@101F3000 {

  18.        compatible= "arm,pl061";

  19.    };


  20.    interrupt-controller@10140000 {

  21.        compatible= "arm,pl190";

  22.    };


  23.    spi@10115000 {

  24.        compatible= "arm,pl022";

  25.    };


  26.    external-bus {

  27.       ethernet@0,0 {

  28.           compatible ="smc,smc91c111";

  29.       };


  30.        i2c@1,0{

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

  32.           rtc@58 {

  33.              compatible = "maxim,ds1338";

  34.           };

  35.       };


  36.        flash@2,0{

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

  38.       };

  39.    };

  40. };




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


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


This tree isn't valid at this point. It is missing informationabout connections between devices. That data will be addedlater.


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


Some things to notice in this tree:


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


 &#9632; Every device node hasa compatible property.


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


 &#9632; The flash node has 2strings in the compatible property. Read on to the next section tolearn why.


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


 &#9632; 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 genericnode names that should be used wherever possible.



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





Understanding the compatibleProperty


理解compatible 属性


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


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


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


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


For example, the Freescale MPC8349 System on Chip (SoC) has aserial device which implements the National Semiconductor ns16550register interface. The compatible property for the MPC8349 serialdevice should therefore be: compatible = "fsl,mpc8349-uart","ns16550". In this case, fsl,mpc8349-uart specifies the exactdevice, and ns16550 states that it is register-level compatiblewith 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 forhistorical reasons. All new compatible values should use themanufacturer prefix.


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


This practice allows existing device drivers to be bound to anewer device, while still uniquely identifying the exacthardware.


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


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



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





HowAddressing Works


如何编址


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


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


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


 &#9632; reg


 &#9632; #address-cells


 &#9632; #size-cells


Each addressable device gets a reg which is a list of tuples inthe form reg = <address1 length1 [address2 length2][address3 length3] ... >. Each tuple represents anaddress range used by the device. Each address value is a list ofone or more 32 bit integers called cells. Similarly, the lengthvalue 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 ofvariable size, the #address-cells and #size-cells properties in theparent node are used to state how many cells are in each field. Orin other words, interpreting a reg property correctly requires theparent node's #address-cells and #size-cells values. To see howthis all works, lets add the addressing properties to the sampledevice tree, starting with the CPUs.



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





CPUaddressing


CPU 编址


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



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




  1.     cpus {

  2.        #address-cells =<1>;

  3.       #size-cells = <0>;

  4.        cpu@0 {

  5.            compatible= "arm,cortex-a9";

  6.           reg =<0>;

  7.        };

  8.        cpu@1 {

  9.            compatible= "arm,cortex-a9";

  10.           reg =<1>;

  11.        };

  12.     };



In the cpus node, #address-cells is set to 1, and #size-cells isset to 0. This means that child reg values are a single uint32 thatrepresent the address with no size field. In this case, the twocpus are assigned addresses 0 and 1. #size-cells is 0 for cpu nodesbecause 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 thenode name. By convention, if a node has a reg property, then thenode name must include the unit-address, which is the first addressvalue in the reg property.



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





Memory MappedDevices


内存映射设备


Instead of single address values like found in the cpu nodes, amemory mapped device is assigned a range of addresses that it willrespond to. #size-cells is used to state how large the length fieldis in each child reg tuple. In the following example, each addressvalue 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 valueof 2 for #address-cells and #size-cells to get 64 bit addressing inthe device tree.



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




  1. / {

  2.    #address-cells =<1>;

  3.    #size-cells =<1>;


  4.     ...


  5.     serial@101f0000 {

  6.        compatible = "arm,pl011";

  7.        reg = <0x101f0000 0x1000>;

  8.     };


  9.     serial@101f2000 {

  10.        compatible = "arm,pl011";

  11.        reg = <0x101f2000 0x1000>;

  12.     };


  13.     gpio@101f3000 {

  14.        compatible = "arm,pl061";

  15.        reg = <0x101f30000x1000

  16.             0x101f4000 0x0010>;

  17.     };


  18.    interrupt-controller@10140000 {

  19.        compatible = "arm,pl190";

  20.        reg = <0x10140000 0x1000>;

  21.     };


  22.     spi@10115000 {

  23.        compatible = "arm,pl022";

  24.        reg = <0x10115000 0x1000>;

  25.     };


  26.     ...

  27. };



Each device is assigned a base address, and the size of theregion it is assigned. The GPIO device address in this example isassigned two address ranges; 0x101f3000...0x101f3fff and0x101f4000..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 withdiscrete chip select lines. Since each parent node defines theaddressing domain for its children, the address mapping can bechosen to best describe the system. The code below show addressassignment for devices attached to the external bus with the chipselect number encoded into the address.



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




  1. external-bus {

  2.        #address-cells =<2>

  3.       #size-cells = <1>;


  4.        ethernet@0,0 {

  5.            compatible= "smc,smc91c111";

  6.           reg = <0 00x1000>;

  7.        };


  8.        i2c@1,0 {

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

  10.           reg = <1 00x1000>;

  11.            rtc@58{

  12.               compatible ="maxim,ds1338";

  13.            };

  14.        };


  15.        flash@2,0 {

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

  17.           reg = <2 00x4000000>;

  18.        };

  19.     };



The external-bus uses 2 cells for the address value; one for thechip select number, and one for the offset from the base of thechip select. The length field remains as a single cell since onlythe offset portion of the address needs to have a range. So, inthis example, each reg entry contains 3 cells; the chipselectnumber,

原创粉丝点击