Linux 設備樹device tree 使用手冊

  • 摘要:設備樹使用手冊Thispagewalksthroughhowtowriteadevicetreeforanewmachine.Itisintendedtoprovideanoverviewofdevicetreeconceptsandhowtheyareusedtodescribeamachine.本文將介紹如何爲一個新機器編寫設備樹。我們準備提供一個有關設備樹概念的概述和如何使用這些設備樹來描述一個機器。Forafulltechnicaldescriptionofdevic
  • 設備樹使用手冊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 Property3 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 Node7 Advanced Topics高級主題 7.1 Advanced Sample Machine 7.2 PCI Host Bridge7.2.1 PCI Bus numbering7.2.2 PCI Address Translation 7.3 Advanced Interrupt Mapping8 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>; /* each number (cell) is a uint32 */ 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 " , . 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 { [email protected] {compatible = "arm,cortex-a9"; }; [email protected] { compatible = "arm,cortex-a9"; }; };}; 
    The compatible property in each cpu node is a string that specifies the exact cpu model in the form , , 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 [@ ]. 
    現在應該花點時間來討論命名約定了。每個節點必須有一個“<名稱>[@<設備地址>]”形式的名字。 
    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, [email protected] &; [email protected]). 
    See section 2.2.1 of the ePAPR spec for full details about node naming. 
    同級節點命名必須是唯一的,但只要地址不同,多個節點也可以使用一樣的通用名稱(例如 [email protected] 和[email protected])。關於節點命名的更多細節請參考 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 { [email protected] {compatible = "arm,cortex-a9";}; [email protected] {compatible = "arm,cortex-a9";};}; 
    [email protected] {compatible = "arm,pl011";}; 
    [email protected] {compatible = "arm,pl011";}; 
    [email protected] {compatible = "arm,pl061";}; 
    [email protected] {compatible = "arm,pl190";}; 
    [email protected] {compatible = "arm,pl022";}; 
    external-bus { [email protected],0 {compatible = "smc,smc91c111";}; 
    [email protected],0 {compatible = "acme,a1234-i2c-bus"; [email protected] { compatible = "maxim,ds1338";};}; 
    [email protected],0 {compatible = "samsung,k8f1315ebm", "cfi-flash";};};};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 " , ". 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 則說明這是與美國國家半導體 ns16550UART的寄存器級兼容。 
    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 = . 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>; [email protected] {compatible = "arm,cortex-a9"; reg = <0>;};[email protected] {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>; 
    ... 
    [email protected] {compatible = "arm,pl011"; reg = <0x101f0000 0x1000 >;}; 
    [email protected] {compatible = "arm,pl011"; reg = <0x101f2000 0x1000 >;}; 
    [email protected] {compatible = "arm,pl061"; reg = <0x101f3000 0x10000x101f4000 0x0010>;}; 
    [email protected] {compatible = "arm,pl190"; reg = <0x10140000 0x1000 >;}; 
    [email protected] {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>; 
    [email protected],0 {compatible = "smc,smc91c111"; reg = <0 0 0x1000>;}; 
    [email protected],0 {compatible = "acme,a1234-i2c-bus"; reg = <1 0 0x1000>; [email protected] { compatible = "maxim,ds1338";};}; 
    [email protected],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, the offset, and the length. 
    外部總線的地址值使用了兩個 cell,一個用於片選號;另一個則用於片選基址的偏移量。而長度字段則還是單個 cell,這是因爲只有地址的偏移部分才需要一個範圍量。所以,在這個例子中,每個 reg 項都有三個 cell:片選號、偏移量和長度。 
    Since the address domains are contained to a node and its children, parent nodes are free to define whatever addressing scheme makes sense for the bus. Nodes outside of the immediate parent and child nodes do not normally have 
    to care about the local addressing domain, and addresses have to be mapped to get from one domain to another. 
    由於地址域是包含於一個節點及其子節點的,所以父節點可以自由的定義任何對於該總線來說有意義的編址方案。那些在直接父節點和子節點以外的節點通常不關心本地地址域,而地址應該從一個域映射到另一個域。 
    Non Memory Mapped Devices 
    非內存映射設備 
    Other devices are not memory mapped on the processor bus. They can have address ranges, but they are not directly accessible by the CPU. Instead the parent device's driver would perform indirect access on behalf of the CPU. 
    其他的設備沒有被映射到處理機總線上。雖然這些設備可以有一個地址範圍,但他們並不是由 CPU 直接訪問。取而代之的是,父設備的驅動程序會代表 CPU 執行簡介訪問。 
    To take the example of i2c devices, each device is assigned an address, but there is no length or range associated with it. This looks much the same as CPU address assignments. 
    以 i2c 設備爲例,每個設備都分配了一個地址,但並沒有與之關聯的長度或範圍信息。這看起來和 CPU 的地址分配很像。[email protected],0 {compatible = "acme,a1234-i2c-bus"; #address-cells = <1>; #size-cells = <0>;reg = <1 0 0x1000>;[email protected] { compatible = "maxim,ds1338";reg = <58>;};}; 
    Ranges (Address Translation) 
    範圍(地址轉換) 
    We've talked about how to assign addresses to devices, but at this point those addresses are only local to the device node. It doesn't yet describe how to map from those address to an address that the CPU can use. 
    我們已經討論瞭如何給設備分配地址,但目前來說這些地址還只是設備節點的本地地址,我們還沒有描述如何將這些地址映射成 CPU 可使用的地址。 
    The root node always describes the CPU's view of the address space. Child nodes of the root are already using the CPU's address domain, and so do not need any explicit mapping. For example, the [email protected] device is directly 
    assigned the address 0x101f0000. 
    根節點始終描述的是 CPU 視角的地址空間。根節點的子節點已經使用的是 CPU 的地址域,所以它們不需要任何直接映射。例如,[email protected] 設備就是直接分配的 0x101f0000 地址。 
    Nodes that are not direct children of the root do not use the CPU's address domain. In order to get a memory mapped address the device tree must specify how to translate addresses from one domain to another. The ranges property 
    is used for this purpose. 
    那些非根節點直接子節點的節點就沒有使用 CPU 地址域。爲了得到一個內存映射地址,設備樹必須指定從一個域到另一個域地址轉換地方法,而 ranges 屬性就爲此而生。 
    Here is the sample device tree with the ranges property added. 
    下面就是一個添加了 ranges 屬性的示例設備樹。/ {compatible = "acme,coyotes-revenge";#address-cells = <1>;#size-cells = <1>;...external-bus {#address-cells = <2>#size-cells = <1>; ranges = <0 0 0x101000000x10000 // Chipselect 1, Ethernet1 0 0x101600000x10000 // Chipselect 2, i2c controller2 0 0x300000000x10000000>; // Chipselect 3, NOR Flash 
    [email protected],0 {compatible = "smc,smc91c111";reg = <0 0 0x1000>;}; 
    [email protected],0 {compatible = "acme,a1234-i2c-bus";#address-cells = <1>;#size-cells = <0>;reg = <1 0 0x1000>;[email protected] { compatible = "maxim,ds1338"; reg = <58>;};}; 
    [email protected],0 {compatible = "samsung,k8f1315ebm", "cfi-flash";reg = <2 0 0x4000000>;};};}; 
    ranges is a list of address translations. Each entry in the ranges table is a tuple containing the child address, the parent address, and the size of the region in the child address space. The size of each field is determined 
    by taking the child's #address-cells value, the parent's #address-cells value, and the child's #size-cells value. For the external bus in our example, the child address is 2 cells, the parent address is 1 cell, and the size is also 1 cell. Three ranges are 
    being translated: 
    ranges 是一個地址轉換列表。ranges 表中的每一項都是一個包含子地址、父地址和在子地址空間中區域大小的元組。每個字段的值都取決於子節點的 #address-cells 、父節點的 #address-cells 和子節點的 #size-cells。以本例中的外部總線來說,子地址是 2 cell、父地址是 1 cell、區域大小也是 1 cell。那麼三個 ranges 被翻譯爲: 
    Offset 0 from chip select 0 is mapped to address range 0x10100000..0x1010ffff 
    從片選 0 開始的偏移量 0 被映射爲地址範圍:0x10100000..0x1010ffff 
    Offset 0 from chip select 1 is mapped to address range 0x10160000..0x1016ffff 
    從片選 0 開始的偏移量 1 被映射爲地址範圍:0x10160000..0x1016ffff 
    Offset 0 from chip select 2 is mapped to address range 0x30000000..0x10000000 
    從片選 0 開始的偏移量 2 被映射爲地址範圍:0x30000000..0x10000000 
    Alternately, if the parent and child address spaces are identical, then a node can instead add an empty ranges property. The presence of an empty ranges property means addresses in the child address space are mapped 1:1 onto 
    the parent address space. 
    另外,如果父地址空間和子地址空間是相同的,那麼該節點可以添加一個空的 range 屬性。一個空的 range 屬性意味着子地址將被 1:1 映射到父地址空間。 
    You might ask why address translation is used at all when it could all be written with 1:1 mapping. Some busses (like PCI) have entirely different address spaces whose details need to be exposed to the operating system. Others 
    have DMA engines which need to know the real address on the bus. Sometimes devices need to be grouped together because they all share the same software programmable physical address mapping. Whether or not 1:1 mappings should be used depends a lot on the information 
    needed by the Operating system, and on the hardware design. 
    你有可能會問當全都可以設計成 1:1 映射的時候爲何還要使用地址轉換。答案就是,有一些具有完全不同地址空間的總線(比如 PCI),而它們的細節需要暴露給操作系統。另外一些帶有 DMA 引擎的設備需要知道總線上的真實地址。有時有需要將設備組合到一塊,因爲他們共享相同的軟件可編程物理地址映射。是否應該使用 1:1 映射在很大程度上取決於來自操作系統的信息以及硬件設計。 
    You should also notice that there is no ranges property in the [email protected],0 node. The reason for this is that unlike the external bus, devices on the i2c bus are not memory mapped on the CPU's address domain. Instead, the CPU indirectly 
    accesses the [email protected] device via the [email protected],0 device. The lack of a ranges property means that a device cannot be directly accessed by any device other than it's parent. 
    你還應該注意到在 [email protected],0 節點中並沒有 range 屬性。不同於外部總線,這裏的原因是 i2c 總線上的設備並沒有被內存映射到 CPU 的地址域。相反,CPU 將通過 [email protected],0 設備間接訪問 [email protected] 設備。缺少 ranges 屬性意味着這個設備將不能被出他的父設備之外的任何設備直接訪問。 
    How Interrupts Work 
    中斷如何工作 
    ----------------------------------------- 
    Unlike address range translation which follows the natural structure of the tree, Interrupt signals can originate from and terminate on any device in a machine. Unlike device addressing which is naturally expressed in the device 
    tree, interrupt signals are expressed as links between nodes independent of the tree. Four properties are used to describe interrupt connections: 
    與遵循樹的自然結構而進行的地址轉換不同,機器上的任何設備都可以發起和終止中斷信號。另外地址的編址也不同於中斷信號,前者是設備樹的自然表示,而後者者表現爲獨立於設備樹結構的節點之間的鏈接。描述中斷連接需要四個屬性: 
    ■interrupt-controller - An empty property declaring a node as a device that receives interrupt signals 
    interrupt-controller - 一個空的屬性定義該節點作爲一個接收中斷信號的設備。 
    ■#interrupt-cells - This is a property of the interrupt controller node. It states how many cells are in an interrupt specifier for this interrupt controller (Similar to #address-cells 
    and #size-cells). 
    #interrupt-cells - 這是一箇中斷控制器節點的屬性。它聲明瞭該中斷控制器的中斷指示符中 cell 的個數(類似於 #address-cells 和 #size-cells)。 
    ■interrupt-parent - A property of a device node containing a phandle to the interrupt controller that it is attached to. Nodes that do not have an interrupt-parent property can also 
    inherit the property from their parent node. 
    interrupt-parent - 這是一個設備節點的屬性,包含一個指向該設備連接的中斷控制器的 phandle。那些沒有 interrupt-parent 的節點則從它們的父節點中繼承該屬性。 
    ■interrupts - A property of a device node containing a list of interrupt specifiers, one for each interrupt output signal on the device. 
    interrupts - 一個設備節點屬性,包含一箇中斷指示符的列表,對應於該設備上的每個中斷輸出信號。 
    An interrupt specifier is one or more cells of data (as specified by #interrupt-cells) that specifies which interrupt input the device is attached to. Most devices only have a single interrupt output as shown in the example 
    below, but it is possible to have multiple interrupt outputs on a device. The meaning of an interrupt specifier depends entirely on the binding for the interrupt controller device. Each interrupt controller can decide how many cells it need to uniquely define 
    an interrupt input. 
    中斷指示符是一個或多個 cell 的數據(由 #interrupt-cells 指定),這些數據指定了該設備連接至哪些輸入中斷。在以下的例子中,大部分設備都只有一個輸出中斷,但也有可能在一個設備上有多個輸出中斷。一箇中斷指示符的意義完全取決於與中斷控制器設備的 binding。每個中斷控制器可以決定使用幾個 cell 來唯一的定義一個輸入中斷。 
    The following code adds interrupt connections to our Coyote's Revenge example machine: 
    下面的代碼爲我們 Coyote's Revenge 模型機添加了中斷連接:


    點擊(此處)摺疊或打開

    / {compatible = "acme,coyotes-revenge";#address-cells = <1>;#size-cells = <1>; interrupt-parent = <∫c>; 
    cpus {#address-cells = <1>;#size-cells = <0>; [email protected] {compatible = "arm,cortex-a9";reg = <0>;};[email protected] {compatible = "arm,cortex-a9";reg = <1>;};}; 
    [email protected] {compatible = "arm,pl011";reg = <0x101f0000 0x1000 >; interrupts = < 1 0 >;}; 
    [email protected] {compatible = "arm,pl011";reg = <0x101f2000 0x1000 >; interrupts = < 2 0 >;}; 
    [email protected] {compatible = "arm,pl061";reg = <0x101f3000 0x10000x101f4000 0x0010>; interrupts = < 3 0 >;}; 
    intc: [email protected] {compatible = "arm,pl190";reg = <0x10140000 0x1000 >; interrupt-controller;#interrupt-cells = <2>;}; 
    [email protected] {compatible = "arm,pl022";reg = <0x10115000 0x1000 >; interrupts = < 4 0 >;}; 
    external-bus {#address-cells = <2>#size-cells = <1>;ranges = <0 0 0x101000000x10000 // Chipselect 1, Ethernet1 0 0x101600000x10000 // Chipselect 2, i2c controller2 0 0x300000000x1000000>; // Chipselect 3, NOR Flash 
    [email protected],0 {compatible = "smc,smc91c111";reg = <0 0 0x1000>; interrupts = < 5 2 >;}; 
    [email protected],0 {compatible = "acme,a1234-i2c-bus";#address-cells = <1>;#size-cells = <0>;reg = <1 0 0x1000>; interrupts = < 6 2 >; [email protected] { compatible = "maxim,ds1338"; reg = <58>;interrupts = < 7 3 >;};}; 
    [email protected],0 {compatible = "samsung,k8f1315ebm", "cfi-flash";reg = <2 0 0x4000000>;};};};Some things to notice: 
    需要注意的事情: 
    ■The machine has a single interrupt controller, [email protected] 
    這個機器只有一箇中斷控制器: [email protected]。 
    ■The label 'intc:' has been added to the interrupt controller node, and the label was used to assign a phandle to the interrupt-parent property in the root node. This interrupt-parent 
    value becomes the default for the system because all child nodes inherit it unless it is explicitly overridden. 
    中斷控制器節點上添加了‘inc:’標籤,該標籤用於給根節點的 interrupt-parent 屬性分配一個 phandle。這個 interrupt-parent 將成爲本系統的默認值,因爲所有的子節點都將繼承它,除非顯示覆寫這個屬性。 
    ■Each device uses an interrupt property to specify a different interrupt input line. 
    每個設備使用 interrupts 屬性來不同的中斷輸入線。 
    ■#interrupt-cells is 2, so each interrupt specifier has 2 cells. This example uses the common pattern of using the first cell to encode the interrupt line number, and the second cell 
    to encode flags such as active high vs. active low, or edge vs. level sensitive. For any given interrupt controller, refer to the controller's binding documentation to learn how the specifier is encoded. 
    #interrupt-cells 是 2,所以每個中斷指示符都有 2 個 cell。本例使用一種通用的模式,也就是用第一個 cell 來編碼中斷線號;然後用第二個 cell 編碼標誌位,比如高電平/低電平有效,或者邊緣/水平觸發。對於任何給定的中斷控制器,請參考該控制器的 binding 文檔以瞭解指示符如何編碼。 
    Device Specific Data 
    設備特定數據 
    ----------------------------------------- 
    Beyond the common properties, arbitrary properties and child nodes can be added to nodes. Any data needed by the operating system can be added as long as some rules are followed. 
    除了通用屬性以外,一個節點中可以添加任何屬性和子節點。只要遵循一些規則,可以添加任何操作系統所需要的數據。 
    First, new device-specific property names should use a manufacture prefix so that they don't conflict with existing standard property names. 
    首先,新的設備特定屬性的名字都應該使用製造商前綴,以避免和現有標準屬性名相沖突。 
    Second, the meaning of the properties and child nodes must be documented in a binding so that a device driver author knows how to interpret the data. A binding documents what a particular compatible value means, what properties 
    it should have, what child nodes it might have, and what device it represents. Each unique compatible value should have its own binding (or claim compatibility with another compatible value). Bindings for new devices are documented in this wiki. See the Main 
    Page for a description of the documentation format and review process. 
    其次,屬性和子節點的含義必須存檔在 binding 文檔中,以便設備驅動程序的程序員知道如何解釋這些數據。一個 binding 記錄了一個特定 compatible 值的意義、應該包含什麼樣的屬性、有可能包含那些子節點、以及它代表了什麼樣的設備。每個特別的 compatible 值都應該有一個它自己的 binding(或者要求與其他 compatible 值兼容)。新設備的 binding 存檔在本 wiki 
    中。請查看主頁上的文檔格式描述和審覈流程。 
    Third, post new bindings for review on the [email protected] mailing list. Reviewing new bindings catches a lot of common mistakes that will cause problems in the future. 
    第三,使用郵件列表 [email protected] 發送新的 binding 以進行審覈。新 binding 的審覈可以捕獲很多可能在以後導致問題的常見錯誤。 
    Special Nodes 
    特殊節點 
    ----------------------------------------- 
    aliases Node 
    aliases 節點 
    A specific node is normally referenced by the full path, like /external-bus/ [email protected],0, but that gets cumbersome when what a user really wants to know is, "which device is eth0?" The aliases node can be used to assign a short 
    alias to a full device path. For example: 
    引用一個特定的節點通常使用全路徑,如 /external-bus/ [email protected],0,但當用戶真真想知道的只是“那個設備是 eth0?”時,這樣的全路徑就變得很冗長。這時,aliases 節點就可以用於指定一個設備全路徑的別名。例如:aliases {ethernet0 = ð0;serial0 = &;serial0;}; 
    The operating system is welcome to use the aliases when assigning an identifier to a device. 
    當給一個設備分配一個識別符是操作系統將非常樂意使用別名。 
    You'll notice a new syntax used here. The property = &;label; syntax assigns the full node path referenced by the label as a string property. This is different from the phandle = < &;label >; form used earlier which inserts a 
    phandle value into a cell. 
    在這裏你會發現一個新語法。property = &;label;,將作爲字符串屬性並通過引用標籤來指定一個節點的全路徑。這與之前的 phandle = < &;label >; 形式不同,這是把一個 phandle 值插入進一個 cell。 
    chosen Node 
    chosen節點 
    The chosen node doesn't represent a real device, but serves as a place for passing data between firmware and the operating system, like boot arguments. Data in the chosen node does not represent the hardware. Typically the 
    chosen node is left empty in .dts source files and populated at boot time. 
    chosen 節點並不代表一個真正的設備,只是作爲一個爲固件和操作系統之間傳遞數據的地方,比如引導參數。chosen 節點裏的數據也不代表硬件。通常,chosen 節點在 .dts 源文件中爲空,並在啓動時填充。 
    In our example system, firmware might add the following to the chosen node: 
    在我們的示例系統中,固件可以往 chosen 節點添加以下信息:chosen {bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";}; 
    Advanced Topics 
    高級主題 
    ----------------------------------------- 
    Advanced Sample Machine 
    高級模型機 
    Now that we've got the basics defined, let's add some hardware to the sample machine to discuss some of the more complicated use cases. 
    現在,我們已經掌握了基本的定義,接下來讓我們往模型機裏添加一些硬件,以討論一些更復雜的用例。 
    The advanced sample machine adds a PCI host bridge with control registers memory mapped to 0x10180000, and BARs programmed to start above the address 0x80000000. 
    高級模型機添加了一個 PCI 主橋,其控制寄存器映射到內存 0x10180000,並且 BARs 編程至以地址 0x80000000 爲起始。 
    Given what we already know about the device tree, we can start with the addition of the following node to describe the PCI host bridge. 
    既然關於設備樹我們已經有所瞭解了,那麼我們就從以下所示新增加的節點來介紹 PCI 主橋。 [email protected] {compatible = "arm,versatile-pci-hostbridge", "pci";reg = <0x10180000 0x1000>;interrupts = <8 0>;}; 
    PCI Host Bridge 
    PCI 主橋 
    This section describes the Host/PCI bridge node. 
    本節介紹 Host/PCI 橋節點。 
    Note, some basic knowledge of PCI is assumed in this section. This is NOT a tutorial about PCI, if you need some more in depth information, please read[1]. You can also refer to either ePAPR or the PCI Bus Binding to Open Firmware. 
    A complete working example for a Freescale MPC5200 can be found here. 
    注,本節將假定讀者瞭解 PCI 的一些基本知識。本文並不是 PCI 教程,想要了解更深入的信息,請閱讀 [1]。你也可以參考 ePAPR 或 PCI Bus Binding to Open Firmware(http://playground.sun.com/1275/bindings/pci/pci2_1.pdf)。還可以訪問
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章